**** Merged from HEAD ****
authorMartin Baulig <martin@novell.com>
Thu, 22 Jan 2004 04:08:55 +0000 (04:08 -0000)
committerMartin Baulig <martin@novell.com>
Thu, 22 Jan 2004 04:08:55 +0000 (04:08 -0000)
svn path=/trunk/mcs/; revision=22378

27 files changed:
mcs/gmcs/AssemblyInfo.cs
mcs/gmcs/ChangeLog
mcs/gmcs/Makefile
mcs/gmcs/attribute.cs
mcs/gmcs/cfold.cs
mcs/gmcs/class.cs
mcs/gmcs/codegen.cs
mcs/gmcs/convert.cs
mcs/gmcs/cs-parser.jay
mcs/gmcs/cs-tokenizer.cs
mcs/gmcs/decl.cs
mcs/gmcs/delegate.cs
mcs/gmcs/driver.cs
mcs/gmcs/ecore.cs
mcs/gmcs/expression.cs
mcs/gmcs/flowanalysis.cs
mcs/gmcs/gen-treedump.cs
mcs/gmcs/interface.cs
mcs/gmcs/iterators.cs
mcs/gmcs/location.cs
mcs/gmcs/modifiers.cs
mcs/gmcs/namespace.cs
mcs/gmcs/report.cs
mcs/gmcs/rootcontext.cs
mcs/gmcs/statement.cs
mcs/gmcs/support.cs
mcs/gmcs/typemanager.cs

index 8fcadbb111563eddcb7d76fe80e7ceec3995f800..a80bb2813a07c57a32a57140f4729ba6d58e29cf 100644 (file)
@@ -1,7 +1,7 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
-[assembly: AssemblyVersion("0.28")]
+[assembly: AssemblyVersion("0.29.99")]
 [assembly: AssemblyTitle ("Mono C# Compiler")]
 [assembly: AssemblyDescription ("Mono C# Compiler with Generics")]
 [assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")]
index fec29f077105c48e155ef2f7775ea6ea03901a35..137ecd0cc8683dd4283dbd4d9acf29df80d624d7 100755 (executable)
@@ -1,3 +1,310 @@
+2003-12-31 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * report.cs, codegen.cs: Give the real stack trace to
+       the error when an exception is thrown.
+
+2003-12-31 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: only allocate hashtables for ifaces if 
+       it is an iface!
+
+2003-12-31 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: fix the error from cs0121-2.cs
+       (a parent interface has two child interfaces that
+       have a function with the same name and 0 params
+       and the function is called through the parent).
+
+2003-12-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs, rootcontext.cs, typmanager.cs: do not
+       leak pointers.
+
+2003-12-28 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * codegen.cs: remove stack for the ec flow branching.
+       It is already a linked list, so no need.
+
+2003-12-27 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * Makefile: Allow custom profiler here.
+
+2003-12-26 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * typemanager.cs (LookupType):
+         - Use a static char [], because split takes
+           a param array for args, so it was allocating
+           every time.
+         - Do not store true in a hashtable, it boxes.
+
+2003-12-26 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * flowanalysis.cs: bytify common enums.
+
+2003-12-25 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * modifiers.cs: Add a new set of flags for the
+       flags allowed on explicit interface impls.
+       * cs-parser.jay: catch the use of modifiers in
+       interfaces correctly.
+       * class.cs: catch private void IFoo.Blah ().
+
+       All related to bug #50572.
+
+2003-12-25 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: Rewrite the consistant accessability checking.
+       Accessability is not linear, it must be implemented in
+       a tableish way. Fixes #49704.
+
+2003-12-25 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Handle negation in a checked context.
+       We must use subtraction from zero. Fixes #38674.
+
+2003-12-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs: Ignore static void main in DLLs.
+       * rootcontext.cs: Handle the target type here,
+       since we are have to access it from class.cs
+       * driver.cs: account for the above.
+
+2003-12-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * report.cs: Give line numbers and files if available.
+
+2003-12-20  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs: Implement /addmodule.
+
+       * typemanager.cs:  Change 'modules' field so it now contains Modules not
+       ModuleBuilders.
+
+2003-12-20  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineMembers): Don't do the CS0649 check here.
+       (FieldBase.IsAssigned): Removed this field.
+       (FieldBase.SetAssigned): New public method.
+       (TypeContainer.Emit): Make the CS0169/CS0649 checks actually work.
+
+2003-12-20  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (LocalVariableReference.DoResolve): Don't set
+       `vi.Used' if we're called from DoResolveLValue().
+
+       * statement.cs (Block.DoResolve): `ec.DoEndFlowBranching()' now
+       returns the usage vector it just merged into the current one -
+       pass this one to UsageWarning().
+       (Block.UsageWarning): Take the `FlowBranching.UsageVector' instead
+       of the `EmitContext', don't call this recursively on our children.
+
+2003-12-19  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs: Implement /target:module.
+
+2003-12-18  Zoltan Varga  <vargaz@freemail.hu>
+
+       * support.cs (CharArrayHashtable): New helper class.
+
+       * cs-tokenizer.cs: Store keywords in a hashtable indexed by 
+       char arrays, not strings, so we can avoid creating a string in
+       consume_identifier if the identifier is a keyword.
+
+2003-12-16  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (LocalInfo.Assigned): Removed this property.
+       (LocalInfo.Flags): Removed `Assigned'.
+       (LocalInfo.IsAssigned): New public method; takes the EmitContext
+       and uses flow analysis.
+       (Block.UsageWarning): Made this method private.
+       (Block.Resolve): Call UsageWarning() if appropriate.
+
+       * expression.cs (LocalVariableReference.DoResolve): Always set
+       LocalInfo.Used here.
+
+2003-12-13  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Statement.DoEmit, Statement.Emit): Don't return
+       any value here; we're now using flow analysis to figure out
+       whether a statement/block returns a value.
+
+2003-12-13  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (UsageVector.MergeFinallyOrigins): Made this
+       working again.
+       (FlowBranching.MergeFinally): Don't call
+       `branching.CheckOutParameters()' here, this is called in
+       MergeTopBlock().
+       (FlowBranchingException.AddSibling): Call MergeFinallyOrigins()
+       when adding the `finally' vector.       
+
+2003-12-13  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs
+       (UsageVector.MergeJumpOrigins, FlowBranching.Label): Make this
+       actually work and also fix #48962.
+
+2003-12-12 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: Do not check System.Object for nested types,
+       since we know it does not have any. Big bang for buck:
+
+       BEFORE:
+          Run 1:   8.35 seconds
+          Run 2:   8.32 seconds
+          corlib:  17.99 seconds
+       AFTER:
+          Run 1:   8.17 seconds
+          Run 2:   8.17 seconds
+          corlib:  17.39 seconds
+
+2003-12-11 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs (FindMembers): Allocate arraylists on demand. Most of the
+       time we are returning 0 members, so we save alot here.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (UsageVector.MergeResult): Renamed this back to
+       `MergeChild()', also just take the `FlowBranching' as argument;
+       call Merge() on it and return the result.
+       (FlowBranching.Merge): We don't need to do anything if we just
+       have one sibling.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs: Use a list of `UsageVector's instead of storing
+       them in an `ArrayList' to reduce memory usage.  Thanks to Ben
+       Maurer for this idea.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (MergeResult): This class is now gone; we now
+       use the `UsageVector' for this.  The reason for this is that if a
+       branching just has one sibling, we don't need to "merge" them at
+       all - that's the next step to do.
+       (FlowBranching.Merge): We now return a `UsageVector' instead of a
+       `MergeResult'.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       Reworked flow analyis and made it more precise and bug-free.  The
+       most important change is that we're now using a special `Reachability'
+       class instead of having "magic" meanings of `FlowReturns'.  I'll
+       do some more cleanups and optimizations and also add some more
+       documentation this week.
+
+       * flowanalysis.cs (Reachability): Added `Throws' and `Barrier';
+       largely reworked this class.
+       (FlowReturns): Removed `Unreachable' and `Exception'; we now use
+       the new `Reachability' class instead of having "magic" values here.
+       (FlowBranching): We're now using an instance of `Reachability'
+       instead of having separate `Returns', `Breaks' etc. fields.
+
+       * codegen.cs (EmitContext.EmitTopBlock): Set `has_ret' solely
+       based on flow analysis; ignore the return value of block.Emit ().
+
+2003-12-10  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs typemanager.cs: Find the mono extensions to corlib even
+       if they are private.
+
+2003-12-09  Martin Baulig  <martin@ximian.com>
+
+       * flowanalyis.cs (FlowBranching.Return, Goto, Throw): Removed;
+       call them directly on the UsageVector.
+
+2003-12-09  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.MergeChild, MergeTopBlock):
+       Changed return type from `FlowReturns' to `Reachability'.
+
+2003-12-09  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.Reachability): New sealed class.
+       (FlowBranching.MergeResult): Replaced the `Returns', `Breaks' and
+       `Reachable' fields with a single `Reachability' one.
+
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs (FindMembers): Remove foreach's.
+
+       Bootstrap times:
+       
+       BEFORE
+               Run 1:   8.74 seconds
+               Run 2:   8.71 seconds
+       
+       AFTER
+               Run 1:   8.64 seconds
+               Run 2:   8.58 seconds
+       
+
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * cs-parser.jay:
+       * gen-treedump.cs:
+       * statement.cs:
+       This patch does a few things:
+               1. EmptyStatement is now a singleton, so it is never reallocated.
+               2. All blah is EmptyStatement constructs have been changed to
+                  blah == EmptyStatement.Value, which is much faster and valid
+                  now that EmptyStatement is a singleton.
+               3. When resolving a block, rather than allocating a new array for
+                  the non-empty statements, empty statements are replaced with
+                  EmptyStatement.Value
+               4. Some recursive functions have been made non-recursive.
+       Mainly the performance impact is from (3), however (1) and (2) are needed for
+       this to work. (4) does not make a big difference in normal situations, however
+       it makes the profile look saner.
+
+       Bootstrap times:
+
+       BEFORE
+       9.25user 0.23system 0:10.28elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k
+       9.34user 0.13system 0:10.23elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k
+       Total memory allocated: 56397 KB
+       
+       AFTER
+       9.13user 0.09system 0:09.64elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
+       8.96user 0.24system 0:10.13elapsed 90%CPU (0avgtext+0avgdata 0maxresident)k
+       Total memory allocated: 55666 KB
+
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * support.cs: Rewrite DoubleHash to use its own impl. Is faster
+       than the hashtable in a hashtable version
+
+       * decl.cs: Right now, whenever we try to lookup a type inside a namespace,
+       we always end up concating a string. This results in a huge perf
+       loss, because many strings have to be tracked by the GC. In this
+       patch, we first use a hashtable that works with two keys, so that
+       the strings do not need to be concat'ed.
+
+       Bootstrap times:
+       BEFORE
+               Run 1:   8.74 seconds
+               Run 2:   8.71 seconds
+       
+       AFTER
+               Run 1:   8.65 seconds
+               Run 2:   8.56 seconds
+       
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * Makefile: Add a new target `do-time' that does a quick and simple
+       profile, leaving easy to parse output.
+
+2003-12-08  Zoltan Varga  <vargaz@freemail.hu>
+
+       * codegen.cs (Init): Create the dynamic assembly with 
+       AssemblyBuilderAccess.Save, to enable some optimizations in the runtime.
+
+2003-12-02 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * support.cs: Make the PtrHashtable use only one
+       instance of its comparer.
+
 2003-11-30  Zoltan Varga  <vargaz@freemail.hu>
 
        * typemanager.cs: Fix lookup of GetNamespaces.
index d379bf3a9697ee68a043f676f6cab93c7bb2feb2..055cbfa5d049abf8c58c2f3f902bc1f0890412ea 100644 (file)
@@ -93,5 +93,22 @@ ctest:
        -rm mcs2.exe mcs3.exe
        make btest USE_MCS_FLAGS= 
 
+# we need this because bash tries to use its own crappy timer
+FRIENDLY_TIME = $(shell which time) -f'%U seconds'
+
+do-time : mcs.exe
+       @ echo -n "Run 1:   "
+       @ $(FRIENDLY_TIME) $(RUNTIME) ./mcs.exe $(USE_MCS_FLAGS) /target:exe /out:mcs2.exe $(all_sources) > /dev/null || (echo FAILED; exit 1)
+       @ echo -n "Run 2:   "
+       @ $(FRIENDLY_TIME) $(RUNTIME) ./mcs2.exe $(USE_MCS_FLAGS) /target:exe /out:mcs3.exe $(all_sources) > /dev/null || (echo FAILED; exit 1)
+       @ echo -n "corlib:  "
+       @ rm -f ../class/lib/mscorlib.dll
+       @ (cd ../class/corlib ; make BOOTSTRAP_MCS="$(FRIENDLY_TIME) mono ../../mcs/mcs.exe" > /dev/null ) || (echo FAILED; exit 1)
+
+PROFILER=default
+
+profile : mcs.exe
+       $(RUNTIME) --profile=$(PROFILER) ./mcs.exe $(USE_MCS_FLAGS) /target:exe /out:mcs2.exe $(all_sources)
+
 response:
        echo $(all_sources) > res
index 3e65aeb44d3006bb750ff71fe600fafd5fc54309..7667150fe489cfee96d440931ca38052a8b7c05d 100644 (file)
@@ -1051,7 +1051,9 @@ namespace Mono.CSharp {
                        CallingConvention cc = CallingConvention.Winapi;\r
                        CharSet charset = CharSet.Ansi;\r
                        bool preserve_sig = true;\r
+#if FIXME\r
                        bool exact_spelling = false;\r
+#endif\r
                        bool set_last_err = false;\r
                        string entry_point = null;\r
 \r
@@ -1096,8 +1098,10 @@ namespace Mono.CSharp {
                                                        entry_point = (string) c.GetValue ();\r
                                                else if (member_name == "SetLastError")\r
                                                        set_last_err = (bool) c.GetValue ();\r
+#if FIXME\r
                                                else if (member_name == "ExactSpelling")\r
                                                        exact_spelling = (bool) c.GetValue ();\r
+#endif\r
                                                else if (member_name == "PreserveSig")\r
                                                        preserve_sig = (bool) c.GetValue ();\r
                                        } else { \r
index d4d130ca5dac81a3638e6650cb0848f6f759173d..a87f83621c78de07fb3440e5347e0923dc32edd4 100755 (executable)
@@ -59,16 +59,22 @@ namespace Mono.CSharp {
                                // converted to type ulong.  or an error ocurrs if the other
                                // operand is of type sbyte, short, int or long
                                //
+#if WRONG
                                Constant match, other;
+#endif
                                        
                                if (left is ULongConstant){
+#if WRONG
                                        other = right;
                                        match = left;
+#endif
                                        if (!(right is ULongConstant))
                                                right = right.ToULong (loc);
                                } else {
+#if WRONG
                                        other = left;
                                        match = right;
+#endif
                                        left = left.ToULong (loc);
                                }
 
index d20c50d489beb47d9ba414ddd980b57b0d27b466..92e9191e0de7a3e31c98b499ff7d410091fffde3 100755 (executable)
@@ -137,17 +137,9 @@ namespace Mono.CSharp {
                public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Location l)
                        : base (ns, parent, name, l)
                {
-                       string n;
                        types = new ArrayList ();
 
-                       if (parent == null)
-                               n = "";
-                       else 
-                               n = parent.Name;
-
                        base_class_name = null;
-
-                       //Console.WriteLine ("New class " + name + " inside " + n);
                }
 
                public AdditionResult AddConstant (Const constant)
@@ -531,7 +523,6 @@ namespace Mono.CSharp {
                public bool EmitFieldInitializers (EmitContext ec)
                {
                        ArrayList fields;
-                       ILGenerator ig = ec.ig;
                        Expression instance_expr;
                        
                        if (ec.IsStatic){
@@ -1109,14 +1100,6 @@ namespace Mono.CSharp {
                        if (fields != null)
                                DefineMembers (fields, defined_names);
 
-                       if ((RootContext.WarningLevel >= 4) && (fields != null)) {
-                               foreach (Field f in fields) {
-                                       if (((f.ModFlags & Modifiers.READONLY) != 0) && !f.IsAssigned)
-                                               Report.Warning (649, "Field `" + MakeFQN (Name, f.Name) + "; is never " +
-                                                               "assigned and will ever have its default value");
-                               }
-                       }
-
                        if (this is Class){
                                if (instance_constructors == null){
                                        if (default_constructor == null)
@@ -1248,7 +1231,7 @@ namespace Mono.CSharp {
                public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
                                                        MemberFilter filter, object criteria)
                {
-                       ArrayList members = new ArrayList ();
+                       ArrayList members = null;
 
                        int modflags = 0;
                        if ((bf & BindingFlags.Public) != 0)
@@ -1280,35 +1263,52 @@ namespace Mono.CSharp {
 
                        if ((mt & MemberTypes.Field) != 0) {
                                if (fields != null) {
-                                       foreach (Field f in fields) {
+                                       int len = fields.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Field f = (Field) fields [i];
+                                               
                                                if ((f.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((f.ModFlags & static_mask) != static_flags)
                                                        continue;
 
                                                FieldBuilder fb = f.FieldBuilder;
-                                               if (fb != null && filter (fb, criteria) == true)
+                                               if (fb != null && filter (fb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (fb);
                                        }
                                }
+                               }
 
                                if (constants != null) {
-                                       foreach (Const con in constants) {
+                                       int len = constants.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Const con = (Const) constants [i];
+                                               
                                                if ((con.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((con.ModFlags & static_mask) != static_flags)
                                                        continue;
 
                                                FieldBuilder fb = con.FieldBuilder;
-                                               if (fb != null && filter (fb, criteria) == true)
+                                               if (fb != null && filter (fb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (fb);
                                        }
                                }
                        }
+                       }
 
                        if ((mt & MemberTypes.Method) != 0) {
                                if (methods != null) {
-                                       foreach (Method m in methods) {
+                                       int len = methods.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Method m = (Method) methods [i];
+                                               
                                                if ((m.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((m.ModFlags & static_mask) != static_flags)
@@ -1316,26 +1316,40 @@ namespace Mono.CSharp {
                                                
                                                MethodBuilder mb = m.MethodBuilder;
 
-                                               if (mb != null && filter (mb, criteria) == true)
+                                               if (mb != null && filter (mb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (mb);
                                        }
                                }
+                               }
+
+                               if (operators != null) {
+                                       int len = operators.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Operator o = (Operator) operators [i];
 
-                               if (operators != null){
-                                       foreach (Operator o in operators) {
                                                if ((o.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((o.ModFlags & static_mask) != static_flags)
                                                        continue;
                                                
                                                MethodBuilder ob = o.OperatorMethodBuilder;
-                                               if (ob != null && filter (ob, criteria) == true)
+                                               if (ob != null && filter (ob, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (ob);
                                        }
                                }
+                               }
+
+                               if (properties != null) {
+                                       int len = properties.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Property p = (Property) properties [i];
 
-                               if (properties != null){
-                                       foreach (Property p in properties){
                                                if ((p.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((p.ModFlags & static_mask) != static_flags)
@@ -1344,17 +1358,28 @@ namespace Mono.CSharp {
                                                MethodBuilder b;
 
                                                b = p.GetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
+                                               }
 
                                                b = p.SetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
                                        }
                                }
+                               }
+                               
+                               if (indexers != null) {
+                                       int len = indexers.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Indexer ix = (Indexer) indexers [i];
                                
-                               if (indexers != null){
-                                       foreach (Indexer ix in indexers){
                                                if ((ix.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((ix.ModFlags & static_mask) != static_flags)
@@ -1363,33 +1388,52 @@ namespace Mono.CSharp {
                                                MethodBuilder b;
 
                                                b = ix.GetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
+                                               }
 
                                                b = ix.SetBuilder;
-                                               if (b != null && filter (b, criteria) == true)
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (b);
                                        }
                                }
                        }
+                       }
 
                        if ((mt & MemberTypes.Event) != 0) {
-                               if (events != null)
-                                       foreach (Event e in events) {
+                               if (events != null) {
+                                       int len = events.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Event e = (Event) events [i];
+                                               
                                                if ((e.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((e.ModFlags & static_mask) != static_flags)
                                                        continue;
 
                                                MemberInfo eb = e.EventBuilder;
-                                               if (eb != null && filter (eb, criteria) == true)
+                                               if (eb != null && filter (eb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (e.EventBuilder);
                                        }
                        }
+                               }
+                       }
                        
                        if ((mt & MemberTypes.Property) != 0){
-                               if (properties != null)
-                                       foreach (Property p in properties) {
+                               if (properties != null) {
+                                       int len = properties.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Property p = (Property) properties [i];
+                                               
                                                if ((p.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((p.ModFlags & static_mask) != static_flags)
@@ -1397,12 +1441,19 @@ namespace Mono.CSharp {
 
                                                MemberInfo pb = p.PropertyBuilder;
                                                if (pb != null && filter (pb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (p.PropertyBuilder);
                                                }
                                        }
+                               }
+
+                               if (indexers != null) {
+                                       int len = indexers.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Indexer ix = (Indexer) indexers [i];
 
-                               if (indexers != null)
-                                       foreach (Indexer ix in indexers) {
                                                if ((ix.ModFlags & modflags) == 0)
                                                        continue;
                                                if ((ix.ModFlags & static_mask) != static_flags)
@@ -1410,87 +1461,136 @@ namespace Mono.CSharp {
 
                                                MemberInfo ib = ix.PropertyBuilder;
                                                if (ib != null && filter (ib, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (ix.PropertyBuilder);
                                                }
                                        }
                        }
+                       }
                        
                        if ((mt & MemberTypes.NestedType) != 0) {
-                               if (types != null){
-                                       foreach (TypeContainer t in types) {
+                               if (types != null) {
+                                       int len = types.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               TypeContainer t = (TypeContainer) types [i];
+                                               
                                                if ((t.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = t.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                                members.Add (tb);
                                        }
                                }
+                               }
+
+                               if (enums != null) {
+                                       int len = enums.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Enum en = (Enum) enums [i];
 
-                               if (enums != null){
-                                       foreach (Enum en in enums){
                                                if ((en.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = en.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (tb);
                                        }
                                }
+                               }
+                               
+                               if (delegates != null) {
+                                       int len = delegates.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Delegate d = (Delegate) delegates [i];
                                
-                               if (delegates != null){
-                                       foreach (Delegate d in delegates){
                                                if ((d.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = d.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (tb);
                                        }
                                }
+                               }
+
+                               if (interfaces != null) {
+                                       int len = interfaces.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Interface iface = (Interface) interfaces [i];
 
-                               if (interfaces != null){
-                                       foreach (Interface iface in interfaces){
                                                if ((iface.ModFlags & modflags) == 0)
                                                        continue;
 
                                                TypeBuilder tb = iface.TypeBuilder;
-                                               if (tb != null && (filter (tb, criteria) == true))
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                        members.Add (tb);
                                        }
                                }
                        }
+                       }
 
                        if ((mt & MemberTypes.Constructor) != 0){
                                if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
-                                       foreach (Constructor c in instance_constructors){
+                                       int len = instance_constructors.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Constructor c = (Constructor) instance_constructors [i];
+                                               
                                                ConstructorBuilder cb = c.ConstructorBuilder;
-                                               if (cb != null)
-                                                       if (filter (cb, criteria) == true)
+                                               if (cb != null && filter (cb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
                                                                members.Add (cb);
                                        }
                                }
+                               }
 
                                if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
                                        ConstructorBuilder cb =
                                                default_static_constructor.ConstructorBuilder;
                                        
-                                       if (cb != null)
-                                       if (filter (cb, criteria) == true)
+                                       if (cb != null && filter (cb, criteria) == true) {
+                                               if (members == null)
+                                                       members = new ArrayList ();
+                                               
                                                members.Add (cb);
                                }
                        }
+                       }
 
                        //
                        // Lookup members in parent if requested.
                        //
                        if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
                                MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
+                               if (list.Count > 0) {
+                                       if (members == null)
+                                               members = new ArrayList ();
+                                       
                                members.AddRange (list);
                        }
+                       }
 
                        Timer.StopTimer (TimerType.TcFindMembers);
 
+                       if (members == null)
+                               return MemberList.Empty;
+                       else
                        return new MemberList (members);
                }
 
@@ -1587,10 +1687,10 @@ namespace Mono.CSharp {
                        if (RootContext.WarningLevel >= 3) {
                                if (fields != null){
                                        foreach (Field f in fields) {
-                                               if ((f.ModFlags & Modifiers.PUBLIC) != 0)
+                                               if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
                                                        continue;
                                                
-                                               if (f.status == 0){
+                                               if ((f.status & Field.Status.USED) == 0){
                                                        Report.Warning (
                                                                169, f.Location, "Private field " +
                                                                MakeName (f.Name) + " is never used");
@@ -1628,11 +1728,12 @@ namespace Mono.CSharp {
                
                public override void CloseType ()
                {
+                       if (Created)
+                               return;
+                       
                        try {
-                               if (!Created){
                                        Created = true;
                                        TypeBuilder.CreateType ();
-                               }
                        } catch (TypeLoadException){
                                //
                                // This is fine, the code still created the type
@@ -1666,6 +1767,29 @@ namespace Mono.CSharp {
                        if (Delegates != null)
                                foreach (Delegate d in Delegates)
                                        d.CloseType ();
+                       
+                       types = null;
+                       properties = null;
+                       enums = null;
+                       delegates = null;
+                       fields = null;
+                       initialized_fields = null;
+                       initialized_static_fields = null;
+                       constants = null;
+                       interfaces = null;
+                       interface_order = null;
+                       methods = null;
+                       events = null;
+                       indexers = null;
+                       operators = null;
+                       ec = null;
+                       default_constructor = null;
+                       default_static_constructor = null;
+                       type_bases = null;
+                       attributes = null;
+                       ifaces = null;
+                       parent_container = null;
+                       member_cache = null;
                }
 
                public string MakeName (string n)
@@ -2544,7 +2668,7 @@ namespace Mono.CSharp {
                        // This is used to track the Entry Point,
                        //
                        if (Name == "Main" &&
-                           ((ModFlags & Modifiers.STATIC) != 0) && 
+                           ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
                            (RootContext.MainClass == null ||
                             RootContext.MainClass == container.TypeBuilder.FullName)){
                                 if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
@@ -2574,6 +2698,7 @@ namespace Mono.CSharp {
                {
                        MethodData.Emit (container, Block, this);
                        Block = null;
+                       MethodData = null;
                }
 
                void IIteratorContainer.SetYields ()
@@ -3440,6 +3565,8 @@ namespace Mono.CSharp {
 
                protected MethodAttributes flags;
 
+               protected readonly int explicit_mod_flags;
+
                //
                // The "short" name of this property / indexer / event.  This is the
                // name without the explicit interface.
@@ -3483,6 +3610,7 @@ namespace Mono.CSharp {
                                      Attributes attrs, Location loc)
                        : base (name, loc)
                {
+                       explicit_mod_flags = mod;
                        Type = type;
                        ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
                        OptAttributes = attrs;
@@ -3764,6 +3892,8 @@ namespace Mono.CSharp {
                                if (!container.VerifyImplements (InterfaceType, ShortName, Name, Location))
                                        return false;
                                
+                               Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
+                               
                                IsExplicitImpl = true;
                        } else
                                IsExplicitImpl = false;
@@ -3802,8 +3932,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool IsAssigned;
-
                protected readonly Object init;
                // Private.
                Expression init_expr;
@@ -3832,6 +3960,11 @@ namespace Mono.CSharp {
 
                        return init_expr;
                }
+
+               public void SetAssigned ()
+               {
+                       status |= Status.ASSIGNED;
+               }
        }
 
        //
@@ -4584,8 +4717,6 @@ namespace Mono.CSharp {
                //
                // Are we implementing an interface ?
                //
-               bool IsImplementing = false;
-               
                public Indexer (DeclSpace ds, Expression type, string int_type, int flags,
                                Parameters parameters, Accessor get_block, Accessor set_block,
                                Attributes attrs, Location loc)
@@ -4712,11 +4843,6 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (GetData != null)
-                               IsImplementing = GetData.IsImplementing;
-                       else if (SetData != null)
-                               IsImplementing = SetData.IsImplementing;
-
                        //
                        // Define the PropertyBuilder if one of the following conditions are met:
                        // a) we're not implementing an interface indexer.
index 3eff8d66167641af36c708ff06e35b96a52c680c..3985e955ccc32f6174bcf7a121e70d7184bfc8fd 100755 (executable)
@@ -92,7 +92,7 @@ namespace Mono.CSharp {
                        
                        current_domain = AppDomain.CurrentDomain;
                        AssemblyBuilder = current_domain.DefineDynamicAssembly (
-                               an, AssemblyBuilderAccess.RunAndSave, Dirname (name));
+                               an, AssemblyBuilderAccess.Save, Dirname (name));
 
                        //
                        // Pass a path-less name to DefineDynamicModule.  Wonder how
@@ -321,7 +321,7 @@ namespace Mono.CSharp {
                /// </summary>
                public bool InEnumContext;
 
-               protected Stack FlowStack;
+               FlowBranching current_flow_branching;
                
                public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig,
                                    Type return_type, int code_flags, bool is_constructor)
@@ -351,8 +351,6 @@ namespace Mono.CSharp {
                        }
                        loc = l;
 
-                       FlowStack = new Stack ();
-                       
                        if (ReturnType == TypeManager.void_type)
                                ReturnType = null;
                }
@@ -371,7 +369,7 @@ namespace Mono.CSharp {
 
                public FlowBranching CurrentBranching {
                        get {
-                               return (FlowBranching) FlowStack.Peek ();
+                               return current_flow_branching;
                        }
                }
 
@@ -381,11 +379,8 @@ namespace Mono.CSharp {
                // </summary>
                public FlowBranching StartFlowBranching (FlowBranching.BranchingType type, Location loc)
                {
-                       FlowBranching cfb = FlowBranching.CreateBranching (CurrentBranching, type, null, loc);
-
-                       FlowStack.Push (cfb);
-
-                       return cfb;
+                       current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, null, loc);
+                       return current_flow_branching;
                }
 
                // <summary>
@@ -393,7 +388,6 @@ namespace Mono.CSharp {
                // </summary>
                public FlowBranching StartFlowBranching (Block block)
                {
-                       FlowBranching cfb;
                        FlowBranching.BranchingType type;
 
                        if (CurrentBranching.Type == FlowBranching.BranchingType.Switch)
@@ -401,22 +395,31 @@ namespace Mono.CSharp {
                        else
                                type = FlowBranching.BranchingType.Block;
 
-                       cfb = FlowBranching.CreateBranching (CurrentBranching, type, block, block.StartLocation);
+                       current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, block, block.StartLocation);
+                       return current_flow_branching;
+               }
 
-                       FlowStack.Push (cfb);
+               // <summary>
+               //   Ends a code branching.  Merges the state of locals and parameters
+               //   from all the children of the ending branching.
+               // </summary>
+               public FlowBranching.UsageVector DoEndFlowBranching ()
+               {
+                       FlowBranching old = current_flow_branching;
+                       current_flow_branching = current_flow_branching.Parent;
 
-                       return cfb;
+                       return current_flow_branching.MergeChild (old);
                }
 
                // <summary>
                //   Ends a code branching.  Merges the state of locals and parameters
                //   from all the children of the ending branching.
                // </summary>
-               public FlowBranching.FlowReturns EndFlowBranching ()
+               public FlowBranching.Reachability EndFlowBranching ()
                {
-                       FlowBranching cfb = (FlowBranching) FlowStack.Pop ();
+                       FlowBranching.UsageVector vector = DoEndFlowBranching ();
 
-                       return CurrentBranching.MergeChild (cfb);
+                       return vector.Reachability;
                }
 
                // <summary>
@@ -425,7 +428,7 @@ namespace Mono.CSharp {
                // </summary>
                public void KillFlowBranching ()
                {
-                       FlowBranching cfb = (FlowBranching) FlowStack.Pop ();
+                       current_flow_branching = current_flow_branching.Parent;
                }
 
                public void EmitTopBlock (Block block, InternalParameters ip, Location loc)
@@ -445,34 +448,28 @@ namespace Mono.CSharp {
                                        bool old_do_flow_analysis = DoFlowAnalysis;
                                        DoFlowAnalysis = true;
 
-                                       FlowBranching cfb = FlowBranching.CreateBranching (
+                                       current_flow_branching = FlowBranching.CreateBranching (
                                                null, FlowBranching.BranchingType.Block, block, loc);
-                                       FlowStack.Push (cfb);
 
                                        if (!block.Resolve (this)) {
-                                               FlowStack.Pop ();
+                                               current_flow_branching = null;
                                                DoFlowAnalysis = old_do_flow_analysis;
                                                return;
                                        }
 
-                                       cfb = (FlowBranching) FlowStack.Pop ();
-                                       FlowBranching.FlowReturns returns = cfb.MergeTopBlock ();
+                                       FlowBranching.Reachability reachability = current_flow_branching.MergeTopBlock ();
+                                       current_flow_branching = null;
 
                                        DoFlowAnalysis = old_do_flow_analysis;
 
-                                       has_ret = block.Emit (this);
+                                       block.Emit (this);
 
-                                       if ((returns == FlowBranching.FlowReturns.Always) ||
-                                           (returns == FlowBranching.FlowReturns.Exception) ||
-                                           (returns == FlowBranching.FlowReturns.Unreachable))
+                                       if ((reachability.Returns == FlowBranching.FlowReturns.Always) ||
+                                           (reachability.Throws == FlowBranching.FlowReturns.Always) ||
+                                           (reachability.Reachable == FlowBranching.FlowReturns.Never))
                                                has_ret = true;
-
-                                       if (Report.Errors == errors){
-                                               if (RootContext.WarningLevel >= 3)
-                                                       block.UsageWarning ();
                                        }
-                               }
-                           } catch {
+                           } catch (Exception e) {
                                        Console.WriteLine ("Exception caught by the compiler while compiling:");
                                        Console.WriteLine ("   Block that caused the problem begin at: " + loc);
                                        
@@ -480,7 +477,11 @@ namespace Mono.CSharp {
                                                Console.WriteLine ("                     Block being compiled: [{0},{1}]",
                                                                   CurrentBlock.StartLocation, CurrentBlock.EndLocation);
                                        }
-                                       throw;
+                                       
+                                       Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
+                                       Console.WriteLine (Report.FriendlyStackTrace (e));
+                                       
+                                       Environment.Exit (1);
                            }
                        }
 
index 271f501126e11c733bef7a711a07cabe003f8704..4684a3a9326685ed71cb1b78977dbbad6b4faafd 100644 (file)
@@ -1003,7 +1003,6 @@ namespace Mono.CSharp {
                static public Expression ImplicitConversion (EmitContext ec, Expression expr,
                                                             Type target_type, Location loc)
                {
-                       Type expr_type = expr.Type;
                        Expression e;
 
                        if (target_type == null)
index 034a3bb8b92ff5dabe5f7615b881d87a073814dc..82b1b91c7b98bc96df3ee32a718cddb8c74b8c8f 100755 (executable)
@@ -1304,8 +1304,13 @@ interface_member_declaration
        ;
 
 opt_new
-       : /* empty */   { $$ = false; }
-       | NEW           { $$ = true; }
+       : opt_modifiers 
+         {
+               int val = (int) $1;
+               
+               val = Modifiers.Check (Modifiers.NEW, val, 0, lexer.Location);
+               $$ = (bool) (val != 0);
+         }
        ;
 
 interface_method_declaration
index 470e69114051783997fdb8924d766935ee0564da..bf4bb4478e8ed556d0cc61365bcf3b9909ad2cd1 100755 (executable)
@@ -147,7 +147,7 @@ namespace Mono.CSharp
                //\r
                // Class variables\r
                // \r
-               static Hashtable keywords;\r
+               static CharArrayHashtable[] keywords;\r
                static NumberStyles styles;\r
                static NumberFormatInfo csharp_format_info;\r
                \r
@@ -205,97 +205,104 @@ namespace Mono.CSharp
                        }\r
                }\r
 \r
+               static void AddKeyword (string kw, int token) {\r
+                       if (keywords [kw.Length] == null) {\r
+                               keywords [kw.Length] = new CharArrayHashtable (kw.Length);\r
+                       }\r
+                       keywords [kw.Length] [kw.ToCharArray ()] = token;\r
+               }\r
+\r
                static void InitTokens ()\r
                {\r
-                       keywords = new Hashtable ();\r
-\r
-                       keywords.Add ("abstract", Token.ABSTRACT);\r
-                       keywords.Add ("as", Token.AS);\r
-                       keywords.Add ("add", Token.ADD);\r
-                       keywords.Add ("assembly", Token.ASSEMBLY);\r
-                       keywords.Add ("base", Token.BASE);\r
-                       keywords.Add ("bool", Token.BOOL);\r
-                       keywords.Add ("break", Token.BREAK);\r
-                       keywords.Add ("byte", Token.BYTE);\r
-                       keywords.Add ("case", Token.CASE);\r
-                       keywords.Add ("catch", Token.CATCH);\r
-                       keywords.Add ("char", Token.CHAR);\r
-                       keywords.Add ("checked", Token.CHECKED);\r
-                       keywords.Add ("class", Token.CLASS);\r
-                       keywords.Add ("const", Token.CONST);\r
-                       keywords.Add ("continue", Token.CONTINUE);\r
-                       keywords.Add ("decimal", Token.DECIMAL);\r
-                       keywords.Add ("default", Token.DEFAULT);\r
-                       keywords.Add ("delegate", Token.DELEGATE);\r
-                       keywords.Add ("do", Token.DO);\r
-                       keywords.Add ("double", Token.DOUBLE);\r
-                       keywords.Add ("else", Token.ELSE);\r
-                       keywords.Add ("enum", Token.ENUM);\r
-                       keywords.Add ("event", Token.EVENT);\r
-                       keywords.Add ("explicit", Token.EXPLICIT);\r
-                       keywords.Add ("extern", Token.EXTERN);\r
-                       keywords.Add ("false", Token.FALSE);\r
-                       keywords.Add ("finally", Token.FINALLY);\r
-                       keywords.Add ("fixed", Token.FIXED);\r
-                       keywords.Add ("float", Token.FLOAT);\r
-                       keywords.Add ("for", Token.FOR);\r
-                       keywords.Add ("foreach", Token.FOREACH);\r
-                       keywords.Add ("goto", Token.GOTO);\r
-                       keywords.Add ("get", Token.GET);\r
-                       keywords.Add ("if", Token.IF);\r
-                       keywords.Add ("implicit", Token.IMPLICIT);\r
-                       keywords.Add ("in", Token.IN);\r
-                       keywords.Add ("int", Token.INT);\r
-                       keywords.Add ("interface", Token.INTERFACE);\r
-                       keywords.Add ("internal", Token.INTERNAL);\r
-                       keywords.Add ("is", Token.IS);\r
-                       keywords.Add ("lock", Token.LOCK);\r
-                       keywords.Add ("long", Token.LONG);\r
-                       keywords.Add ("namespace", Token.NAMESPACE);\r
-                       keywords.Add ("new", Token.NEW);\r
-                       keywords.Add ("null", Token.NULL);\r
-                       keywords.Add ("object", Token.OBJECT);\r
-                       keywords.Add ("operator", Token.OPERATOR);\r
-                       keywords.Add ("out", Token.OUT);\r
-                       keywords.Add ("override", Token.OVERRIDE);\r
-                       keywords.Add ("params", Token.PARAMS);\r
-                       keywords.Add ("private", Token.PRIVATE);\r
-                       keywords.Add ("protected", Token.PROTECTED);\r
-                       keywords.Add ("public", Token.PUBLIC);\r
-                       keywords.Add ("readonly", Token.READONLY);\r
-                       keywords.Add ("ref", Token.REF);\r
-                       keywords.Add ("remove", Token.REMOVE);\r
-                       keywords.Add ("return", Token.RETURN);\r
-                       keywords.Add ("sbyte", Token.SBYTE);\r
-                       keywords.Add ("sealed", Token.SEALED);\r
-                       keywords.Add ("set", Token.SET);\r
-                       keywords.Add ("short", Token.SHORT);\r
-                       keywords.Add ("sizeof", Token.SIZEOF);\r
-                       keywords.Add ("stackalloc", Token.STACKALLOC);\r
-                       keywords.Add ("static", Token.STATIC);\r
-                       keywords.Add ("string", Token.STRING);\r
-                       keywords.Add ("struct", Token.STRUCT);\r
-                       keywords.Add ("switch", Token.SWITCH);\r
-                       keywords.Add ("this", Token.THIS);\r
-                       keywords.Add ("throw", Token.THROW);\r
-                       keywords.Add ("true", Token.TRUE);\r
-                       keywords.Add ("try", Token.TRY);\r
-                       keywords.Add ("typeof", Token.TYPEOF);\r
-                       keywords.Add ("uint", Token.UINT);\r
-                       keywords.Add ("ulong", Token.ULONG);\r
-                       keywords.Add ("unchecked", Token.UNCHECKED);\r
-                       keywords.Add ("unsafe", Token.UNSAFE);\r
-                       keywords.Add ("ushort", Token.USHORT);\r
-                       keywords.Add ("using", Token.USING);\r
-                       keywords.Add ("virtual", Token.VIRTUAL);\r
-                       keywords.Add ("void", Token.VOID);\r
-                       keywords.Add ("volatile", Token.VOLATILE);\r
-                       keywords.Add ("where", Token.WHERE);\r
-                       keywords.Add ("while", Token.WHILE);\r
+                       keywords = new CharArrayHashtable [64];\r
+\r
+                       AddKeyword ("abstract", Token.ABSTRACT);\r
+                       AddKeyword ("as", Token.AS);\r
+                       AddKeyword ("add", Token.ADD);\r
+                       AddKeyword ("assembly", Token.ASSEMBLY);\r
+                       AddKeyword ("base", Token.BASE);\r
+                       AddKeyword ("bool", Token.BOOL);\r
+                       AddKeyword ("break", Token.BREAK);\r
+                       AddKeyword ("byte", Token.BYTE);\r
+                       AddKeyword ("case", Token.CASE);\r
+                       AddKeyword ("catch", Token.CATCH);\r
+                       AddKeyword ("char", Token.CHAR);\r
+                       AddKeyword ("checked", Token.CHECKED);\r
+                       AddKeyword ("class", Token.CLASS);\r
+                       AddKeyword ("const", Token.CONST);\r
+                       AddKeyword ("continue", Token.CONTINUE);\r
+                       AddKeyword ("decimal", Token.DECIMAL);\r
+                       AddKeyword ("default", Token.DEFAULT);\r
+                       AddKeyword ("delegate", Token.DELEGATE);\r
+                       AddKeyword ("do", Token.DO);\r
+                       AddKeyword ("double", Token.DOUBLE);\r
+                       AddKeyword ("else", Token.ELSE);\r
+                       AddKeyword ("enum", Token.ENUM);\r
+                       AddKeyword ("event", Token.EVENT);\r
+                       AddKeyword ("explicit", Token.EXPLICIT);\r
+                       AddKeyword ("extern", Token.EXTERN);\r
+                       AddKeyword ("false", Token.FALSE);\r
+                       AddKeyword ("finally", Token.FINALLY);\r
+                       AddKeyword ("fixed", Token.FIXED);\r
+                       AddKeyword ("float", Token.FLOAT);\r
+                       AddKeyword ("for", Token.FOR);\r
+                       AddKeyword ("foreach", Token.FOREACH);\r
+                       AddKeyword ("goto", Token.GOTO);\r
+                       AddKeyword ("get", Token.GET);\r
+                       AddKeyword ("if", Token.IF);\r
+                       AddKeyword ("implicit", Token.IMPLICIT);\r
+                       AddKeyword ("in", Token.IN);\r
+                       AddKeyword ("int", Token.INT);\r
+                       AddKeyword ("interface", Token.INTERFACE);\r
+                       AddKeyword ("internal", Token.INTERNAL);\r
+                       AddKeyword ("is", Token.IS);\r
+                       AddKeyword ("lock", Token.LOCK);\r
+                       AddKeyword ("long", Token.LONG);\r
+                       AddKeyword ("namespace", Token.NAMESPACE);\r
+                       AddKeyword ("new", Token.NEW);\r
+                       AddKeyword ("null", Token.NULL);\r
+                       AddKeyword ("object", Token.OBJECT);\r
+                       AddKeyword ("operator", Token.OPERATOR);\r
+                       AddKeyword ("out", Token.OUT);\r
+                       AddKeyword ("override", Token.OVERRIDE);\r
+                       AddKeyword ("params", Token.PARAMS);\r
+                       AddKeyword ("private", Token.PRIVATE);\r
+                       AddKeyword ("protected", Token.PROTECTED);\r
+                       AddKeyword ("public", Token.PUBLIC);\r
+                       AddKeyword ("readonly", Token.READONLY);\r
+                       AddKeyword ("ref", Token.REF);\r
+                       AddKeyword ("remove", Token.REMOVE);\r
+                       AddKeyword ("return", Token.RETURN);\r
+                       AddKeyword ("sbyte", Token.SBYTE);\r
+                       AddKeyword ("sealed", Token.SEALED);\r
+                       AddKeyword ("set", Token.SET);\r
+                       AddKeyword ("short", Token.SHORT);\r
+                       AddKeyword ("sizeof", Token.SIZEOF);\r
+                       AddKeyword ("stackalloc", Token.STACKALLOC);\r
+                       AddKeyword ("static", Token.STATIC);\r
+                       AddKeyword ("string", Token.STRING);\r
+                       AddKeyword ("struct", Token.STRUCT);\r
+                       AddKeyword ("switch", Token.SWITCH);\r
+                       AddKeyword ("this", Token.THIS);\r
+                       AddKeyword ("throw", Token.THROW);\r
+                       AddKeyword ("true", Token.TRUE);\r
+                       AddKeyword ("try", Token.TRY);\r
+                       AddKeyword ("typeof", Token.TYPEOF);\r
+                       AddKeyword ("uint", Token.UINT);\r
+                       AddKeyword ("ulong", Token.ULONG);\r
+                       AddKeyword ("unchecked", Token.UNCHECKED);\r
+                       AddKeyword ("unsafe", Token.UNSAFE);\r
+                       AddKeyword ("ushort", Token.USHORT);\r
+                       AddKeyword ("using", Token.USING);\r
+                       AddKeyword ("virtual", Token.VIRTUAL);\r
+                       AddKeyword ("void", Token.VOID);\r
+                       AddKeyword ("volatile", Token.VOLATILE);\r
+                       AddKeyword ("where", Token.WHERE);\r
+                       AddKeyword ("while", Token.WHILE);\r
 \r
                        if (RootContext.V2){\r
-                               keywords.Add ("__yield", Token.YIELD);\r
-                               keywords.Add ("yield", Token.YIELD);\r
+                               AddKeyword ("__yield", Token.YIELD);\r
+                               AddKeyword ("yield", Token.YIELD);\r
                        }\r
                }\r
 \r
@@ -311,9 +318,16 @@ namespace Mono.CSharp
                        string_builder = new System.Text.StringBuilder ();\r
                }\r
 \r
-               int GetKeyword (string name)\r
+               int GetKeyword (char[] id, int id_len)\r
                {\r
-                       object o = keywords [name];\r
+                       /*\r
+                        * Keywords are stored in an array of hashtables grouped by their\r
+                        * length.\r
+                        */\r
+\r
+                       if ((id_len >= keywords.Length) || (keywords [id_len] == null))\r
+                               return -1;\r
+                       object o = keywords [id_len] [id];\r
 \r
                        if (o == null)\r
                                return -1;\r
@@ -999,7 +1013,6 @@ namespace Mono.CSharp
                //\r
                int getHex (int count, out bool error)\r
                {\r
-                       int [] buffer = new int [8];\r
                        int i;\r
                        int total = 0;\r
                        int c;\r
@@ -1495,7 +1508,6 @@ namespace Mono.CSharp
                //\r
                bool handle_preprocessing_directive (bool caller_is_taking)\r
                {\r
-                       char [] blank = { ' ', '\t' };\r
                        string cmd, arg;\r
                        bool region_directive = false;\r
 \r
@@ -1750,21 +1762,18 @@ namespace Mono.CSharp
                                }\r
                        }\r
 \r
-                       string ids = new String (id_builder, 0, pos);\r
-\r
                        //\r
                        // Optimization: avoids doing the keyword lookup\r
                        // on uppercase letters and _\r
                        //\r
                        if (s >= 'a'){\r
-                               int keyword = GetKeyword (ids);\r
-                               if (keyword == -1 || quoted){\r
-                                       val = ids;\r
-                                       return Token.IDENTIFIER;\r
-                               }\r
+                               int keyword = GetKeyword (id_builder, pos);\r
+                               if (keyword != -1 && !quoted)\r
                                return keyword;\r
                        }\r
-                       val = ids;\r
+\r
+                       val = new String (id_builder, 0, pos);\r
+\r
                        return Token.IDENTIFIER;\r
                }\r
                \r
index 83a7a6def64341ce0b6049ada6bd6a9330f80a4b..7f9ca703f1ec462d06ecd27c455aa97cdfc86862 100755 (executable)
@@ -456,7 +456,6 @@ namespace Mono.CSharp {
                                return true;
 
                        string check_type_name = check_type.FullName;
-                       string type_name = TypeBuilder.FullName;
                        
                        int cio = check_type_name.LastIndexOf ('+');
                        string container = check_type_name.Substring (0, cio);
@@ -471,108 +470,107 @@ namespace Mono.CSharp {
                }
 
                // Access level of a type.
-               enum AccessLevel {
-                       Public                  = 0,
-                       ProtectedInternal       = 1,
-                       Internal                = 2,
-                       Protected               = 3,
-                       Private                 = 4
+               const int X = 1;
+               enum AccessLevel { // Each column represents `is this scope larger or equal to Blah scope'
+                       // Public    Assembly   Protected
+                       Protected           = (0 << 0) | (0 << 1) | (X << 2),
+                       Public              = (X << 0) | (X << 1) | (X << 2),
+                       Private             = (0 << 0) | (0 << 1) | (0 << 2),
+                       Internal            = (0 << 0) | (X << 1) | (0 << 2),
+                       ProtectedOrInternal = (0 << 0) | (X << 1) | (X << 2),
                }
 
-               // Check whether `flags' denotes a more restricted access than `level'
-               // and return the new level.
-               static AccessLevel CheckAccessLevel (AccessLevel level, int flags)
+               static AccessLevel GetAccessLevelFromModifiers (int flags)
                {
-                       AccessLevel old_level = level;
-
                        if ((flags & Modifiers.INTERNAL) != 0) {
-                               if ((flags & Modifiers.PROTECTED) != 0) {
-                                       if ((int) level < (int) AccessLevel.ProtectedInternal)
-                                               level = AccessLevel.ProtectedInternal;
-                               } else {
-                                       if ((int) level < (int) AccessLevel.Internal)
-                                               level = AccessLevel.Internal;
-                               }
-                       } else if ((flags & Modifiers.PROTECTED) != 0) {
-                               if ((int) level < (int) AccessLevel.Protected)
-                                       level = AccessLevel.Protected;
-                       } else if ((flags & Modifiers.PRIVATE) != 0)
-                               level = AccessLevel.Private;
 
-                       return level;
-               }
+                               if ((flags & Modifiers.PROTECTED) != 0)
+                                       return AccessLevel.ProtectedOrInternal;
+                               else
+                                       return AccessLevel.Internal;
 
-               // Return the access level for a new member which is defined in the current
-               // TypeContainer with access modifiers `flags'.
-               AccessLevel GetAccessLevel (int flags)
-               {
-                       if ((flags & Modifiers.PRIVATE) != 0)
+                       } else if ((flags & Modifiers.PROTECTED) != 0)
+                               return AccessLevel.Protected;
+                       else if ((flags & Modifiers.PRIVATE) != 0)
                                return AccessLevel.Private;
-
-                       AccessLevel level;
-                       if (!IsTopLevel && (Parent != null))
-                               level = Parent.GetAccessLevel (flags);
                        else
-                               level = AccessLevel.Public;
+                               return AccessLevel.Public;
+               }
 
-                       return CheckAccessLevel (CheckAccessLevel (level, flags), ModFlags);
+               // What is the effective access level of this?
+               // TODO: Cache this?
+               AccessLevel EffectiveAccessLevel {
+                       get {
+                               AccessLevel myAccess = GetAccessLevelFromModifiers (ModFlags);
+                               if (!IsTopLevel && (Parent != null))
+                                       return myAccess & Parent.EffectiveAccessLevel;
+                               return myAccess;
+                       }
                }
 
-               // Return the access level for type `t', but don't give more access than `flags'.
-               static AccessLevel GetAccessLevel (Type t, int flags)
+               // Return the access level for type `t'
+               static AccessLevel TypeEffectiveAccessLevel (Type t)
                {
-                       if (((flags & Modifiers.PRIVATE) != 0) || t.IsNestedPrivate)
-                               return AccessLevel.Private;
-
-                       AccessLevel level;
-                       if (TypeManager.IsBuiltinType (t))
+                       if (t.IsPublic)
                                return AccessLevel.Public;
-                       else if ((t.DeclaringType != null) && (t != t.DeclaringType))
-                               level = GetAccessLevel (t.DeclaringType, flags);
-                       else {
-                               level = CheckAccessLevel (AccessLevel.Public, flags);
-                       }
+                       if (t.IsNestedPrivate)
+                               return AccessLevel.Private;
+                       if (t.IsNotPublic)
+                               return AccessLevel.Internal;
 
-                       if (t.IsNestedPublic)
-                               return level;
+                       // By now, it must be nested
+                       AccessLevel parentLevel = TypeEffectiveAccessLevel (t.DeclaringType);
 
-                       if (t.IsNestedAssembly || t.IsNotPublic) {
-                               if ((int) level < (int) AccessLevel.Internal)
-                                       level = AccessLevel.Internal;
-                       }
+                       if (t.IsNestedPublic)
+                               return parentLevel;
+                       if (t.IsNestedAssembly)
+                               return parentLevel & AccessLevel.Internal;
+                       if (t.IsNestedFamily)
+                               return parentLevel & AccessLevel.Protected;
+                       if (t.IsNestedFamORAssem)
+                               return parentLevel & AccessLevel.ProtectedOrInternal;
+                       if (t.IsNestedFamANDAssem)
+                               throw new NotImplementedException ("NestedFamANDAssem not implemented, cant make this kind of type from c# anyways");
 
-                       if (t.IsNestedFamily) {
-                               if ((int) level < (int) AccessLevel.Protected)
-                                       level = AccessLevel.Protected;
-                       }
+                       // nested private is taken care of
 
-                       if (t.IsNestedFamORAssem) {
-                               if ((int) level < (int) AccessLevel.ProtectedInternal)
-                                       level = AccessLevel.ProtectedInternal;
-                       }
-
-                       return level;
+                       throw new Exception ("I give up, what are you?");
                }
 
                //
-               // Returns true if `parent' is as accessible as the flags `flags'
-               // given for this member.
+               // This answers `is the type P, as accessible as a member M which has the
+               // accessability @flags which is declared as a nested member of the type T, this declspace'
                //
-               public bool AsAccessible (Type parent, int flags)
+               public bool AsAccessible (Type p, int flags)
                {
-                       while (parent.IsArray || parent.IsPointer || parent.IsByRef)
-                               parent = TypeManager.GetElementType (parent);
-
-                       if (parent.IsGenericParameter)
+                       if (p.IsGenericParameter)
                                return true; // FIXME
 
-                       AccessLevel level = GetAccessLevel (flags);
-                       AccessLevel level2 = GetAccessLevel (parent, flags);
+                       //
+                       // 1) if M is private, its accessability is the same as this declspace.
+                       // we already know that P is accessible to T before this method, so we
+                       // may return true.
+                       //
 
-                       return (int) level >= (int) level2;
+                       if ((flags & Modifiers.PRIVATE) != 0)
+                               return true;
+
+                       while (p.IsArray || p.IsPointer || p.IsByRef)
+                               p = TypeManager.GetElementType (p);
+
+                       AccessLevel pAccess = TypeEffectiveAccessLevel (p);
+                       AccessLevel mAccess = this.EffectiveAccessLevel &
+                               GetAccessLevelFromModifiers (flags);
+
+                       // for every place from which we can access M, we must
+                       // be able to access P as well. So, we want
+                       // For every bit in M and P, M_i -> P_1 == true
+                       // or, ~ (M -> P) == 0 <-> ~ ( ~M | P) == 0
+
+                       return ~ (~ mAccess | pAccess) == 0;
                }
                
-               static DoubleHash dh = new DoubleHash ();
+               static DoubleHash dh = new DoubleHash (1000);
 
                Type LookupInterfaceOrClass (string ns, string name, out bool error)
                {
@@ -583,7 +581,7 @@ namespace Mono.CSharp {
                        error = false;
 
                        if (dh.Lookup (ns, name, out r))
-                               t = (Type) r;
+                               return (Type) r;
                        else {
                                if (ns != ""){
                                        if (Namespace.IsNamespace (ns)){
@@ -595,8 +593,10 @@ namespace Mono.CSharp {
                                        t = TypeManager.LookupType (name);
                        }
                        
-                       if (t != null)
+                       if (t != null) {
+                               dh.Insert (ns, name, t);
                                return t;
+                       }
 
                        //
                        // In case we are fed a composite name, normalize it.
@@ -608,15 +608,18 @@ namespace Mono.CSharp {
                        }
                        
                        parent = RootContext.Tree.LookupByNamespace (ns, name);
-                       if (parent == null)
+                       if (parent == null) {
+                               dh.Insert (ns, name, null);
                                return null;
+                       }
 
                        t = parent.DefineType ();
-                       dh.Insert (ns, name, t);
                        if (t == null){
                                error = true;
                                return null;
                        }
+                       
+                       dh.Insert (ns, name, t);
                        return t;
                }
 
@@ -654,7 +657,7 @@ namespace Mono.CSharp {
                                Type container_type = containing_ds.TypeBuilder;
                                Type current_type = container_type;
 
-                               while (current_type != null) {
+                               while (current_type != null && current_type != TypeManager.object_type) {
                                        string pre = current_type.FullName;
 
                                        t = LookupInterfaceOrClass (pre, name, out error);
@@ -1047,7 +1050,8 @@ namespace Mono.CSharp {
                public readonly IMemberContainer Container;
                protected Hashtable member_hash;
                protected Hashtable method_hash;
-               protected Hashtable interface_hash;
+               
+               Hashtable interface_hash;
 
                /// <summary>
                ///   Create a new MemberCache for the given IMemberContainer `container'.
@@ -1059,12 +1063,14 @@ namespace Mono.CSharp {
                        Timer.IncrementCounter (CounterType.MemberCache);
                        Timer.StartTimer (TimerType.CacheInit);
 
-                       interface_hash = new Hashtable ();
+                       
 
                        // If we have a parent class (we have a parent class unless we're
                        // TypeManager.object_type), we deep-copy its MemberCache here.
                        if (Container.IsInterface) {
                                MemberCache parent;
+                               interface_hash = new Hashtable ();
+                               
                                if (Container.Parent != null)
                                        parent = Container.Parent.MemberCache;
                                else
@@ -1104,13 +1110,6 @@ namespace Mono.CSharp {
                        return hash;
                }
 
-               void AddInterfaces (MemberCache parent)
-               {
-                       foreach (Type iface in parent.interface_hash.Keys) {
-                               if (!interface_hash.Contains (iface))
-                                       interface_hash.Add (iface, true);
-                       }
-               }
 
                /// <summary>
                ///   Add the contents of `new_hash' to `hash'.
@@ -1142,7 +1141,8 @@ namespace Mono.CSharp {
 
                                if (interface_hash.Contains (itype))
                                        continue;
-                               interface_hash.Add (itype, true);
+                               
+                               interface_hash [itype] = null;
 
                                IMemberContainer iface_container =
                                        TypeManager.LookupMemberContainer (itype);
@@ -1150,7 +1150,12 @@ namespace Mono.CSharp {
                                MemberCache iface_cache = iface_container.MemberCache;
 
                                AddHashtable (hash, iface_cache.member_hash);
-                               AddInterfaces (iface_cache);
+                               
+                               if (iface_cache.interface_hash == null)
+                                       continue;
+                               
+                               foreach (Type parent_contains in iface_cache.interface_hash.Keys)
+                                       interface_hash [parent_contains] = null;
                        }
 
                        return hash;
@@ -1191,8 +1196,6 @@ namespace Mono.CSharp {
                void AddMembers (MemberTypes mt, BindingFlags bf, IMemberContainer container)
                {
                        MemberList members = container.GetMembers (mt, bf);
-                       BindingFlags new_bf = (container == Container) ?
-                               bf | BindingFlags.DeclaredOnly : bf;
 
                        foreach (MemberInfo member in members) {
                                string name = member.Name;
index b671ef6f52c6050e8278a40e18a4580aa03b1781..68cb107d8218fcbe7fe445aa75b740f50cfc2829 100644 (file)
@@ -795,8 +795,6 @@ namespace Mono.CSharp {
 \r
                public override void Emit (EmitContext ec)\r
                {\r
-                       Delegate del = TypeManager.LookupDelegate (InstanceExpr.Type);\r
-\r
                        //\r
                        // Invocation on delegates call the virtual Invoke member\r
                        // so we are always `instance' calls\r
index cf559b3806e438276dd659cf7674234e681b032e..1e53f92ee8ccd5e5c54ab7022908ac7cd2013e67 100755 (executable)
@@ -18,7 +18,7 @@ namespace Mono.CSharp
        using System.Text;
        using System.Globalization;
 
-       enum Target {
+       public enum Target {
                Library, Exe, Module, WinExe
        };
        
@@ -40,6 +40,11 @@ namespace Mono.CSharp
                //
                static ArrayList soft_references;
 
+               //
+               // Modules to be linked
+               //
+               static ArrayList modules;
+
                // Lookup paths
                static ArrayList link_paths;
 
@@ -51,9 +56,6 @@ namespace Mono.CSharp
                
                static string first_source;
 
-               static Target target = Target.Exe;
-               static string target_ext = ".exe";
-
                static bool want_debugging_support = false;
 
                static bool parse_only = false;
@@ -145,7 +147,6 @@ namespace Mono.CSharp
                                int token, tokens = 0, errors = 0;
 
                                while ((token = lexer.token ()) != Token.EOF){
-                                       Location l = lexer.Location;
                                        tokens++;
                                        if (token == Token.ERROR)
                                                errors++;
@@ -312,6 +313,52 @@ namespace Mono.CSharp
                        }
                }
 
+               static public void LoadModule (MethodInfo adder_method, string module)
+               {
+                       Module m;
+                       string total_log = "";
+
+                       try {
+                               try {
+                                       m = (Module)adder_method.Invoke (CodeGen.AssemblyBuilder, new object [] { module });
+                               }
+                               catch (TargetInvocationException ex) {
+                                       throw ex.InnerException;
+                               }
+                               TypeManager.AddModule (m);
+
+                       } 
+                       catch (FileNotFoundException){
+                               foreach (string dir in link_paths){
+                                       string full_path = Path.Combine (dir, module);
+                                       if (!module.EndsWith (".netmodule"))
+                                               full_path += ".netmodule";
+
+                                       try {
+                                               try {
+                                                       m = (Module)adder_method.Invoke (CodeGen.AssemblyBuilder, new object [] { full_path });
+                                               }
+                                               catch (TargetInvocationException ex) {
+                                                       throw ex.InnerException;
+                                               }
+                                               TypeManager.AddModule (m);
+                                               return;
+                                       } catch (FileNotFoundException ff) {
+                                               total_log += ff.FusionLog;
+                                               continue;
+                                       }
+                               }
+                               Report.Error (6, "Cannot find module `" + module + "'" );
+                               Console.WriteLine ("Log: \n" + total_log);
+                       } catch (BadImageFormatException f) {
+                               Report.Error(6, "Cannot load module (bad file format)" + f.FusionLog);
+                       } catch (FileLoadException f){
+                               Report.Error(6, "Cannot load module " + f.FusionLog);
+                       } catch (ArgumentNullException){
+                               Report.Error(6, "Cannot load module (null argument)");
+                       }
+               }
+
                /// <summary>
                ///   Loads all assemblies referenced on the command line
                /// </summary>
@@ -703,21 +750,21 @@ namespace Mono.CSharp
                                string type = args [++i];
                                switch (type){
                                case "library":
-                                       target = Target.Library;
-                                       target_ext = ".dll";
+                                       RootContext.Target = Target.Library;
+                                       RootContext.TargetExt = ".dll";
                                        break;
                                        
                                case "exe":
-                                       target = Target.Exe;
+                                       RootContext.Target = Target.Exe;
                                        break;
                                        
                                case "winexe":
-                                       target = Target.WinExe;
+                                       RootContext.Target = Target.WinExe;
                                        break;
                                        
                                case "module":
-                                       target = Target.Module;
-                                       target_ext = ".dll";
+                                       RootContext.Target = Target.Module;
+                                       RootContext.TargetExt = ".dll";
                                        break;
                                default:
                                        TargetUsage ();
@@ -856,21 +903,21 @@ namespace Mono.CSharp
                        case "/target":
                                switch (value){
                                case "exe":
-                                       target = Target.Exe;
+                                       RootContext.Target = Target.Exe;
                                        break;
 
                                case "winexe":
-                                       target = Target.WinExe;
+                                       RootContext.Target = Target.WinExe;
                                        break;
 
                                case "library":
-                                       target = Target.Library;
-                                       target_ext = ".dll";
+                                       RootContext.Target = Target.Library;
+                                       RootContext.TargetExt = ".dll";
                                        break;
 
                                case "module":
-                                       target = Target.Module;
-                                       target_ext = ".netmodule";
+                                       RootContext.Target = Target.Module;
+                                       RootContext.TargetExt = ".netmodule";
                                        break;
 
                                default:
@@ -958,6 +1005,18 @@ namespace Mono.CSharp
                                }
                                return true;
                        }
+                       case "/addmodule": {
+                               if (value == ""){
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               string [] refs = value.Split (new char [] { ';', ',' });
+                               foreach (string r in refs){
+                                       modules.Add (r);
+                               }
+                               return true;
+                       }
                        case "/doc": {
                                if (value == ""){
                                        Report.Error (5, arg + " requires an argument");
@@ -1143,6 +1202,7 @@ namespace Mono.CSharp
                        
                        references = new ArrayList ();
                        soft_references = new ArrayList ();
+                       modules = new ArrayList ();
                        link_paths = new ArrayList ();
 
                        SetupDefaultDefines ();
@@ -1265,18 +1325,37 @@ namespace Mono.CSharp
                                int pos = first_source.LastIndexOf ('.');
 
                                if (pos > 0)
-                                       output_file = first_source.Substring (0, pos) + target_ext;
+                                       output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
                                else
-                                       output_file = first_source + target_ext;
+                                       output_file = first_source + RootContext.TargetExt;
                        }
 
                        CodeGen.Init (output_file, output_file, want_debugging_support);
 
+                       if (RootContext.Target == Target.Module) {
+                               PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+                               if (module_only == null) {
+                                       Report.Error (0, new Location (-1), "Cannot use /target:module on this runtime: try the Mono runtime instead.");
+                                       Environment.Exit (1);
+                               }
+
+                               module_only.SetValue (CodeGen.AssemblyBuilder, true, null);
+                       }
+
                        TypeManager.AddModule (CodeGen.ModuleBuilder);
 
-                       DateTime start = DateTime.Now;
+                       if (modules.Count > 0) {
+                               MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
+                               if (adder_method == null) {
+                                       Report.Error (0, new Location (-1), "Cannot use /addmodule on this runtime: Try the Mono runtime instead.");
+                                       Environment.Exit (1);
+                               }
+
+                               foreach (string module in modules)
+                                       LoadModule (adder_method, module);
+                       }
+
                        TypeManager.ComputeNamespaces ();
-                       DateTime end = DateTime.Now;
                        
                        //
                        // Before emitting, we need to get the core
@@ -1342,20 +1421,20 @@ namespace Mono.CSharp
 
                        PEFileKinds k = PEFileKinds.ConsoleApplication;
                                
-                       if (target == Target.Library || target == Target.Module){
-                               k = PEFileKinds.Dll;
-
-                               if (RootContext.MainClass != null)
-                                       Report.Error (2017, "Can not specify -main: when building module or library");
-                       } else if (target == Target.Exe)
-                               k = PEFileKinds.ConsoleApplication;
-                       else if (target == Target.WinExe)
-                               k = PEFileKinds.WindowApplication;
+                       switch (RootContext.Target) {
+                       case Target.Library:
+                       case Target.Module:
+                               k = PEFileKinds.Dll; break;
+                       case Target.Exe:
+                               k = PEFileKinds.ConsoleApplication; break;
+                       case Target.WinExe:
+                               k = PEFileKinds.WindowApplication; break;
+                       }
 
-                       if (target == Target.Exe || target == Target.WinExe){
+                       if (RootContext.NeedsEntryPoint) {
                                MethodInfo ep = RootContext.EntryPoint;
 
-                               if (ep == null){
+                               if (ep == null) {
                                        if (Report.Errors == 0)
                                                Report.Error (5001, "Program " + output_file +
                                                              " does not have an entry point defined");
@@ -1363,6 +1442,8 @@ namespace Mono.CSharp
                                }
                                
                                CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
+                       } else if (RootContext.MainClass != null) {
+                               Report.Error (2017, "Can not specify -main: when building module or library");
                        }
 
                        //
@@ -1388,7 +1469,8 @@ namespace Mono.CSharp
                                object[] margs = new object [2];
                                Type[] argst = new Type [2];
                                argst [0] = argst [1] = typeof (string);
-                               MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", argst);
+
+                               MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, null, CallingConventions.Any, argst, null);
                                if (embed_res == null) {
                                        Report.Warning (0, new Location (-1), "Cannot embed resources on this runtime: try the Mono runtime instead.");
                                } else {
index f3a371d74ede87d8cfbd2259c8b861267e5a5c6e..6a510740d2cbda16be24f34419ce8a94d64876f3 100755 (executable)
@@ -2601,7 +2601,7 @@ namespace Mono.CSharp {
 
                        FieldBase fb = TypeManager.GetField (FieldInfo);
                        if (fb != null)
-                               fb.IsAssigned = true;
+                               fb.SetAssigned ();
 
                        //
                        // InitOnly fields can only be assigned in constructors
index 1a8d5a6dd9b9db2a284044e94baa47949b1bc559..45866fd0654d2c97898ca51d0dd293630db3f70a 100755 (executable)
@@ -565,15 +565,23 @@ namespace Mono.CSharp {
                public override void Emit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
-                       Type expr_type = Expr.Type;
                        
                        switch (Oper) {
                        case Operator.UnaryPlus:
                                throw new Exception ("This should be caught by Resolve");
                                
                        case Operator.UnaryNegation:
+                               if (ec.CheckState) {
+                                       ig.Emit (OpCodes.Ldc_I4_0);
+                                       if (type == TypeManager.int64_type)
+                                               ig.Emit (OpCodes.Conv_U8);
+                                       Expr.Emit (ec);
+                                       ig.Emit (OpCodes.Sub_Ovf);
+                               } else {
                                Expr.Emit (ec);
                                ig.Emit (OpCodes.Neg);
+                               }
+                               
                                break;
                                
                        case Operator.LogicalNot:
@@ -1792,8 +1800,6 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return null;
 
-                       int errors = Report.Errors;
-
                        type = ec.DeclSpace.ResolveType (target_type, false, Location);
                        
                        if (type == null)
@@ -2192,8 +2198,6 @@ namespace Mono.CSharp {
                Expression CheckShiftArguments (EmitContext ec)
                {
                        Expression e;
-                       Type l = left.Type;
-                       Type r = right.Type;
 
                        e = ForceConversion (ec, right, TypeManager.int32_type);
                        if (e == null){
@@ -2957,7 +2961,6 @@ namespace Mono.CSharp {
                {
                        ILGenerator ig = ec.ig;
                        Type l = left.Type;
-                       Type r = right.Type;
                        OpCode opcode;
 
                        //
@@ -3020,7 +3023,6 @@ namespace Mono.CSharp {
                        right.Emit (ec);
 
                        bool isUnsigned = is_unsigned (left.Type);
-                       IntConstant ic;
                        
                        switch (oper){
                        case Operator.Multiply:
@@ -3569,10 +3571,8 @@ namespace Mono.CSharp {
 #endif
                }
                
-               public override Expression DoResolve (EmitContext ec)
+               protected Expression DoResolve (EmitContext ec, bool is_lvalue)
                {
-                       DoResolveBase (ec);
-
                        Expression e = Block.GetConstantExpression (Name);
                        if (e != null) {
                                local_info.Used = true;
@@ -3584,12 +3584,22 @@ namespace Mono.CSharp {
                        if ((variable_info != null) && !variable_info.IsAssigned (ec, loc))
                                return null;
 
+                       if (!is_lvalue)
+                               local_info.Used = true;
+
                        if (local_info.LocalBuilder == null)
                                return ec.RemapLocal (local_info);
                        
                        return this;
                }
 
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       DoResolveBase (ec);
+
+                       return DoResolve (ec, false);
+               }
+
                override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
                {
                        DoResolveBase (ec);
@@ -3598,7 +3608,7 @@ namespace Mono.CSharp {
                        if (variable_info != null)
                                variable_info.SetAssigned (ec);
 
-                       Expression e = DoResolve (ec);
+                       Expression e = DoResolve (ec, true);
 
                        if (e == null)
                                return null;
@@ -3630,8 +3640,6 @@ namespace Mono.CSharp {
                {
                        ILGenerator ig = ec.ig;
 
-                       local_info.Assigned = true;
-
                        source.Emit (ec);
                        ig.Emit (OpCodes.Stloc, local_info.LocalBuilder);
                }
@@ -4225,8 +4233,29 @@ namespace Mono.CSharp {
 
                        int cand_count = candidate_pd.Count;
 
+                       //
+                       // If there is no best method, than this one
+                       // is better, however, if we already found a
+                       // best method, we cant tell. This happens
+                       // if we have:
+                       // 
+                       //
+                       //      interface IFoo {
+                       //              void DoIt ();
+                       //      }
+                       //      
+                       //      interface IBar {
+                       //              void DoIt ();
+                       //      }
+                       //      
+                       //      interface IFooBar : IFoo, IBar {}
+                       //
+                       // We cant tell if IFoo.DoIt is better than IBar.DoIt
+                       //
+                       // However, we have to consider that
+                       // Trim (); is better than Trim (params char[] chars);
                        if (cand_count == 0 && argument_count == 0)
-                               return 1;
+                               return best == null || best_params ? 1 : 0;
 
                        if (candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS)
                                if (cand_count != argument_count)
@@ -4474,8 +4503,6 @@ namespace Mono.CSharp {
 
                        ParameterData pd = GetParameterData (candidate);
 
-                       int pd_count = pd.Count;
-
                        if (arg_count != pd.Count)
                                return false;
 
@@ -4752,8 +4779,6 @@ namespace Mono.CSharp {
                                Parameter.Modifier pm = pd.ParameterModifier (j);
                                
                                if (pm == Parameter.Modifier.PARAMS){
-                                       Parameter.Modifier am = a.GetParameterModifier ();
-
                                        if ((pm & ~Parameter.Modifier.PARAMS) != a.GetParameterModifier ()) {
                                                if (!Location.IsNull (loc))
                                                        Error_InvalidArguments (
@@ -4833,8 +4858,6 @@ namespace Mono.CSharp {
                        if (expr is BaseAccess)
                                is_base = true;
 
-                       Expression old = expr;
-
                        expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
                        if (expr == null)
                                return null;
@@ -6820,8 +6843,6 @@ namespace Mono.CSharp {
                        // it will fail to find any members at all
                        //
 
-                       int errors = Report.Errors;
-                       
                        Type expr_type = expr.Type;
                        if (expr is TypeExpr){
                                if (!ec.DeclSpace.CheckAccessLevel (expr_type)){
@@ -7182,9 +7203,9 @@ namespace Mono.CSharp {
 
                public override Expression DoResolve (EmitContext ec)
                {
+#if false
                        ExprClass eclass = ea.Expr.eclass;
 
-#if false
                        // As long as the type is valid
                        if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||
                              eclass == ExprClass.Value)) {
@@ -7718,8 +7739,6 @@ namespace Mono.CSharp {
                        if (!CommonResolve (ec))
                                return null;
 
-                       Type right_type = right_side.Type;
-
                        bool found_any = false, found_any_setters = false;
 
                        Indexers ilist = Indexers.GetIndexersForType (current_type, indexer_type, loc);
index 9d8ca8dc9c30367c4106e079fa41263ca0ecb1fc..75eb9c2a19e2d0463d881d9675f23d92fcbf5c2c 100644 (file)
@@ -25,10 +25,13 @@ namespace Mono.CSharp
                // <summary>
                //   The type of a FlowBranching.
                // </summary>
-               public enum BranchingType {
+               public enum BranchingType : byte {
                        // Normal (conditional or toplevel) block.
                        Block,
 
+                       // Conditional.
+                       Conditional,
+
                        // A loop block.
                        LoopBlock,
 
@@ -45,7 +48,8 @@ namespace Mono.CSharp
                // <summary>
                //   The type of one sibling of a branching.
                // </summary>
-               public enum SiblingType {
+               public enum SiblingType : byte {
+                       Block,
                        Conditional,
                        SwitchSection,
                        Try,
@@ -58,7 +62,7 @@ namespace Mono.CSharp
                //   current code block may return to its enclosing block before reaching
                //   its end.
                // </summary>
-               public enum FlowReturns {
+               public enum FlowReturns : byte {
                        Undefined = 0,
 
                        // It can never return.
@@ -70,14 +74,222 @@ namespace Mono.CSharp
 
                        // The code always returns, ie. there's an unconditional return / break
                        // statement in it.
-                       Always,
+                       Always
+               }
 
-                       // The code always throws an exception.
-                       Exception,
+               public sealed class Reachability
+               {
+                       FlowReturns returns, breaks, throws, barrier, reachable;
+
+                       public FlowReturns Returns {
+                               get { return returns; }
+                       }
+                       public FlowReturns Breaks {
+                               get { return breaks; }
+                       }
+                       public FlowReturns Throws {
+                               get { return throws; }
+                       }
+                       public FlowReturns Barrier {
+                               get { return barrier; }
+                       }
+                       public FlowReturns Reachable {
+                               get { return reachable; }
+                       }
+
+                       public Reachability (FlowReturns returns, FlowReturns breaks,
+                                            FlowReturns throws, FlowReturns barrier)
+                       {
+                               this.returns = returns;
+                               this.breaks = breaks;
+                               this.throws = throws;
+                               this.barrier = barrier;
+
+                               update ();
+                       }
+
+                       public Reachability Clone ()
+                       {
+                               Reachability cloned = new Reachability (returns, breaks, throws, barrier);
+                               cloned.reachable = reachable;
+                               return cloned;
+                       }
+
+                       public static void And (ref Reachability a, Reachability b, bool do_break)
+                       {
+                               if (a == null) {
+                                       a = b.Clone ();
+                                       return;
+                               }
+
+                               //
+                               // `break' does not "break" in a Switch or a LoopBlock
+                               //
+                               bool a_breaks = do_break && a.AlwaysBreaks;
+                               bool b_breaks = do_break && b.AlwaysBreaks;
+
+                               bool a_has_barrier, b_has_barrier;
+                               if (do_break) {
+                                       //
+                                       // This is the normal case: the code following a barrier
+                                       // cannot be reached.
+                                       //
+                                       a_has_barrier = a.AlwaysHasBarrier;
+                                       b_has_barrier = b.AlwaysHasBarrier;
+                               } else {
+                                       //
+                                       // Special case for Switch and LoopBlocks: we can reach the
+                                       // code after the barrier via the `break'.
+                                       //
+                                       a_has_barrier = !a.AlwaysBreaks && a.AlwaysHasBarrier;
+                                       b_has_barrier = !b.AlwaysBreaks && b.AlwaysHasBarrier;
+                               }
+
+                               bool a_unreachable = a_breaks || a.AlwaysThrows || a_has_barrier;
+                               bool b_unreachable = b_breaks || b.AlwaysThrows || b_has_barrier;
+
+                               //
+                               // Do all code paths always return ?
+                               //
+                               if (a.AlwaysReturns) {
+                                       if (b.AlwaysReturns || b_unreachable)
+                                               a.returns = FlowReturns.Always;
+                                       else
+                                               a.returns = FlowReturns.Sometimes;
+                               } else if (b.AlwaysReturns) {
+                                       if (a.AlwaysReturns || a_unreachable)
+                                               a.returns = FlowReturns.Always;
+                                       else
+                                               a.returns = FlowReturns.Sometimes;
+                               } else if (!a.MayReturn) {
+                                       if (b.MayReturn)
+                                               a.returns = FlowReturns.Sometimes;
+                                       else
+                                               a.returns = FlowReturns.Never;
+                               } else if (!b.MayReturn) {
+                                       if (a.MayReturn)
+                                               a.returns = FlowReturns.Sometimes;
+                                       else
+                                               a.returns = FlowReturns.Never;
+                               }
+
+                               a.breaks = AndFlowReturns (a.breaks, b.breaks);
+                               a.throws = AndFlowReturns (a.throws, b.throws);
+                               a.barrier = AndFlowReturns (a.barrier, b.barrier);
+
+                               a.reachable = AndFlowReturns (a.reachable, b.reachable);
+                       }
+
+                       public static Reachability Never ()
+                       {
+                               return new Reachability (
+                                       FlowReturns.Never, FlowReturns.Never,
+                                       FlowReturns.Never, FlowReturns.Never);
+                       }
+
+                       void update ()
+                       {
+                               if ((returns == FlowReturns.Always) || (breaks == FlowReturns.Always) ||
+                                   (throws == FlowReturns.Always) || (barrier == FlowReturns.Always))
+                                       reachable = FlowReturns.Never;
+                               else if ((returns == FlowReturns.Never) && (breaks == FlowReturns.Never) &&
+                                        (throws == FlowReturns.Never) && (barrier == FlowReturns.Never))
+                                       reachable = FlowReturns.Always;
+                               else
+                                       reachable = FlowReturns.Sometimes;
+                       }
+
+                       public bool AlwaysBreaks {
+                               get { return breaks == FlowReturns.Always; }
+                       }
+
+                       public bool MayBreak {
+                               get { return breaks != FlowReturns.Never; }
+                       }
+
+                       public bool AlwaysReturns {
+                               get { return returns == FlowReturns.Always; }
+                       }
+
+                       public bool MayReturn {
+                               get { return returns != FlowReturns.Never; }
+                       }
+
+                       public bool AlwaysThrows {
+                               get { return throws == FlowReturns.Always; }
+                       }
+
+                       public bool MayThrow {
+                               get { return throws != FlowReturns.Never; }
+                       }
+
+                       public bool AlwaysHasBarrier {
+                               get { return barrier == FlowReturns.Always; }
+                       }
+
+                       public bool MayHaveBarrier {
+                               get { return barrier != FlowReturns.Never; }
+                       }
+
+                       public bool IsUnreachable {
+                               get { return reachable == FlowReturns.Never; }
+                       }
+
+                       public void SetReturns ()
+                       {
+                               returns = FlowReturns.Always;
+                               update ();
+                       }
+
+                       public void SetReturnsSometimes ()
+                       {
+                               returns = FlowReturns.Sometimes;
+                               update ();
+                       }
+
+                       public void SetBreaks ()
+                       {
+                               breaks = FlowReturns.Always;
+                               update ();
+                       }
 
-                       // The current code block is unreachable.  This happens if it's immediately
-                       // following a FlowReturns.Always block.
-                       Unreachable
+                       public void ResetBreaks ()
+                       {
+                               breaks = FlowReturns.Never;
+                               update ();
+                       }
+
+                       public void SetThrows ()
+                       {
+                               throws = FlowReturns.Always;
+                               update ();
+                       }
+
+                       public void SetBarrier ()
+                       {
+                               barrier = FlowReturns.Always;
+                               update ();
+                       }
+
+                       static string ShortName (FlowReturns returns)
+                       {
+                               switch (returns) {
+                               case FlowReturns.Never:
+                                       return "N";
+                               case FlowReturns.Sometimes:
+                                       return "S";
+                               default:
+                                       return "A";
+                               }
+                       }
+
+                       public override string ToString ()
+                       {
+                               return String.Format ("[{0}:{1}:{2}:{3}:{4}]",
+                                                     ShortName (returns), ShortName (breaks),
+                                                     ShortName (throws), ShortName (barrier),
+                                                     ShortName (reachable));
+                       }
                }
 
                public static FlowBranching CreateBranching (FlowBranching parent, BranchingType type, Block block, Location loc)
@@ -89,6 +301,12 @@ namespace Mono.CSharp
                        case BranchingType.Switch:
                                return new FlowBranchingBlock (parent, type, SiblingType.SwitchSection, block, loc);
 
+                       case BranchingType.SwitchSection:
+                               return new FlowBranchingBlock (parent, type, SiblingType.Block, block, loc);
+
+                       case BranchingType.Block:
+                               return new FlowBranchingBlock (parent, type, SiblingType.Block, block, loc);
+
                        default:
                                return new FlowBranchingBlock (parent, type, SiblingType.Conditional, block, loc);
                        }
@@ -120,11 +338,6 @@ namespace Mono.CSharp
                // </summary>
                public bool Infinite;
 
-               // <summary>
-               //   If we may leave the current loop.
-               // </summary>
-               public bool MayLeaveLoop;
-
                //
                // Private
                //
@@ -142,8 +355,6 @@ namespace Mono.CSharp
                {
                        if (a == FlowReturns.Undefined)
                                return b;
-                       if (b == FlowReturns.Unreachable)
-                               return a;
 
                        switch (a) {
                        case FlowReturns.Never:
@@ -156,21 +367,14 @@ namespace Mono.CSharp
                                return FlowReturns.Sometimes;
 
                        case FlowReturns.Always:
-                               if ((b == FlowReturns.Always) || (b == FlowReturns.Exception))
+                               if (b == FlowReturns.Always)
                                        return FlowReturns.Always;
                                else
                                        return FlowReturns.Sometimes;
 
-                       case FlowReturns.Exception:
-                               if (b == FlowReturns.Exception)
-                                       return FlowReturns.Exception;
-                               else if (b == FlowReturns.Always)
-                                       return FlowReturns.Always;
-                               else
-                                       return FlowReturns.Sometimes;
+                       default:
+                               throw new ArgumentException ();
                        }
-
-                       return b;
                }
 
                // <summary>
@@ -211,12 +415,16 @@ namespace Mono.CSharp
                        // </summary>
                        public readonly UsageVector InheritsFrom;
 
+                       // <summary>
+                       //   This is used to construct a list of UsageVector's.
+                       // </summary>
+                       public UsageVector Next;
+
                        //
                        // Private.
                        //
                        MyBitVector locals, parameters;
-                       FlowReturns RealReturns, RealBreaks, RealReachable;
-                       bool is_finally;
+                       Reachability reachability;
 
                        static int next_id = 0;
                        int id;
@@ -231,20 +439,19 @@ namespace Mono.CSharp
                                this.InheritsFrom = parent;
                                this.CountParameters = num_params;
                                this.CountLocals = num_locals;
-                               this.RealReturns = FlowReturns.Never;
-                               this.RealBreaks = FlowReturns.Never;
-                               this.RealReachable = FlowReturns.Always;
 
                                if (parent != null) {
                                        locals = new MyBitVector (parent.locals, CountLocals);
                                        if (num_params > 0)
                                                parameters = new MyBitVector (parent.parameters, num_params);
-                                       RealReturns = parent.Returns;
-                                       RealBreaks = parent.Breaks;
+
+                                       reachability = parent.Reachability.Clone ();
                                } else {
                                        locals = new MyBitVector (null, CountLocals);
                                        if (num_params > 0)
                                                parameters = new MyBitVector (null, num_params);
+
+                                       reachability = Reachability.Never ();
                                }
 
                                id = ++next_id;
@@ -254,6 +461,19 @@ namespace Mono.CSharp
                                : this (type, parent, loc, parent.CountParameters, parent.CountLocals)
                        { }
 
+                       public UsageVector (MyBitVector parameters, MyBitVector locals,
+                                           Reachability reachability, Location loc)
+                       {
+                               this.Type = SiblingType.Block;
+                               this.Location = loc;
+
+                               this.reachability = reachability;
+                               this.parameters = parameters;
+                               this.locals = locals;
+
+                               id = ++next_id;
+                       }
+
                        // <summary>
                        //   This does a deep copy of the usage vector.
                        // </summary>
@@ -264,16 +484,14 @@ namespace Mono.CSharp
                                retval.locals = locals.Clone ();
                                if (parameters != null)
                                        retval.parameters = parameters.Clone ();
-                               retval.RealReturns = RealReturns;
-                               retval.RealBreaks = RealBreaks;
-                               retval.RealReachable = RealReachable;
+                               retval.reachability = reachability.Clone ();
 
                                return retval;
                        }
 
                        public bool IsAssigned (VariableInfo var)
                        {
-                               if (!var.IsParameter && AlwaysBreaks)
+                               if (!var.IsParameter && Reachability.AlwaysBreaks)
                                        return true;
 
                                return var.IsAssigned (var.IsParameter ? parameters : locals);
@@ -281,15 +499,16 @@ namespace Mono.CSharp
 
                        public void SetAssigned (VariableInfo var)
                        {
-                               if (!var.IsParameter && AlwaysBreaks)
+                               if (!var.IsParameter && Reachability.AlwaysBreaks)
                                        return;
 
+                               IsDirty = true;
                                var.SetAssigned (var.IsParameter ? parameters : locals);
                        }
 
                        public bool IsFieldAssigned (VariableInfo var, string name)
                        {
-                               if (!var.IsParameter && AlwaysBreaks)
+                               if (!var.IsParameter && Reachability.AlwaysBreaks)
                                        return true;
 
                                return var.IsFieldAssigned (var.IsParameter ? parameters : locals, name);
@@ -297,123 +516,87 @@ namespace Mono.CSharp
 
                        public void SetFieldAssigned (VariableInfo var, string name)
                        {
-                               if (!var.IsParameter && AlwaysBreaks)
+                               if (!var.IsParameter && Reachability.AlwaysBreaks)
                                        return;
 
+                               IsDirty = true;
                                var.SetFieldAssigned (var.IsParameter ? parameters : locals, name);
                        }
 
-                       // <summary>
-                       //   Specifies when the current block returns.
-                       //   If this is FlowReturns.Unreachable, then control can never reach the
-                       //   end of the method (so that we don't need to emit a return statement).
-                       //   The same applies for FlowReturns.Exception, but in this case the return
-                       //   value will never be used.
-                       // </summary>
-                       public FlowReturns Returns {
+                       public Reachability Reachability {
                                get {
-                                       return RealReturns;
+                                       return reachability;
                                }
                        }
 
-                       // <summary>
-                       //   Specifies whether control may return to our containing block
-                       //   before reaching the end of this block.  This happens if there
-                       //   is a break/continue/goto/return in it.
-                       //   This can also be used to find out whether the statement immediately
-                       //   following the current block may be reached or not.
-                       // </summary>
-                       public FlowReturns Breaks {
-                               get {
-                                       return RealBreaks;
-                               }
-                       }
-
-                       public FlowReturns Reachable {
-                               get {
-                                       return RealReachable;
-                               }
-                       }
-
-                       public bool AlwaysBreaks {
-                               get {
-                                       return (Breaks == FlowReturns.Always) ||
-                                               (Breaks == FlowReturns.Exception) ||
-                                               (Breaks == FlowReturns.Unreachable);
+                       public void Return ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetReturns ();
                                }
                        }
 
-                       public bool MayBreak {
-                               get {
-                                       return Breaks != FlowReturns.Never;
+                       public void Break ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetBreaks ();
                                }
                        }
 
-                       public bool AlwaysReturns {
-                               get {
-                                       return (Returns == FlowReturns.Always) ||
-                                               (Returns == FlowReturns.Exception);
+                       public void Throw ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetThrows ();
                                }
                        }
 
-                       public bool MayReturn {
-                               get {
-                                       return (Returns == FlowReturns.Sometimes) ||
-                                               (Returns == FlowReturns.Always);
+                       public void Goto ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetBarrier ();
                                }
                        }
 
-                       public void Break ()
+                       // <summary>
+                       //   Merges a child branching.
+                       // </summary>
+                       public UsageVector MergeChild (FlowBranching branching)
                        {
-                               RealBreaks = FlowReturns.Always;
-                       }
+                               UsageVector result = branching.Merge ();
 
-                       public void Return ()
-                       {
-                               RealReturns = FlowReturns.Always;
-                       }
+                               Report.Debug (2, "  MERGING CHILD", this, IsDirty,
+                                             result.ParameterVector, result.LocalVector,
+                                             result.Reachability, Type);
 
-                       public bool IsUnreachable {
-                               get {
-                                       return (Reachable == FlowReturns.Exception) ||
-                                               (Reachable == FlowReturns.Unreachable);
-                               }
-                       }
+                               reachability = result.Reachability;
 
-                       public void Unreachable ()
-                       {
-                               // If we're already unreachable, don't modify the reason why.
-                               if (!IsUnreachable)
-                                       RealReachable = FlowReturns.Unreachable;
-                       }
+                               if (branching.Type == BranchingType.LoopBlock) {
+                                       bool may_leave_loop = reachability.MayBreak;
+                                       reachability.ResetBreaks ();
 
-                       public void NeverReachable ()
-                       {
-                               // If we're already unreachable, don't modify the reason why.
-                               if (!IsUnreachable)
-                                       RealReachable = FlowReturns.Never;
+                                       if (branching.Infinite && !may_leave_loop) {
+                                               if (reachability.Returns == FlowReturns.Sometimes) {
+                                                       // If we're an infinite loop and do not break,
+                                                       // the code after the loop can never be reached.
+                                                       // However, if we may return from the loop,
+                                                       // then we do always return (or stay in the
+                                                       // loop forever).
+                                                       reachability.SetReturns ();
                        }
 
-                       public void Throw ()
-                       {
-                               // If we're already unreachable, don't modify the reason why.
-                               if (!IsUnreachable)
-                                       RealReachable = FlowReturns.Exception;
+                                               reachability.SetBarrier ();
+                                       } else {
+                                               if (reachability.Returns == FlowReturns.Always) {
+                                                       // We're either finite or we may leave the loop.
+                                                       reachability.SetReturnsSometimes ();
                        }
-
-                       // <summary>
-                       //   Merges a child branching.
-                       // </summary>
-                       public FlowReturns MergeChild (MyBitVector new_params, MyBitVector new_locals,
-                                                      FlowReturns new_returns, FlowReturns new_breaks,
-                                                      FlowReturns new_reachable)
-                       {
-                               Report.Debug (2, "MERGING CHILD", this, new_params, new_locals, new_returns, new_breaks,
-                                             new_reachable);
-
-                               RealReturns = new_returns;
-                               RealBreaks = new_breaks;
-                               RealReachable = new_reachable;
+                       }
+                               } else if (branching.Type == BranchingType.Switch)
+                                       reachability.ResetBreaks ();
 
                                //
                                // We've now either reached the point after the branching or we will
@@ -424,27 +607,48 @@ namespace Mono.CSharp
                                // we need to look at (see above).
                                //
 
-                               Report.Debug (2, "MERGING CHILD #1", this, Returns, Breaks, Reachable, new_locals, new_params);
-
-                               if ((Reachable == FlowReturns.Always) || (Reachable == FlowReturns.Sometimes) ||
-                                   (Reachable == FlowReturns.Never)) {
-                                       if ((Returns == FlowReturns.Always) || (Breaks == FlowReturns.Always))
-                                               RealReachable = FlowReturns.Never;
-                                       if ((Type == SiblingType.SwitchSection) && (Reachable != FlowReturns.Never)) {
-                                               Report.Error (163, Location, "Control cannot fall through from one " +
+                               if ((Type == SiblingType.SwitchSection) && !reachability.IsUnreachable) {
+                                       Report.Error (163, Location,
+                                                     "Control cannot fall through from one " +
                                                              "case label to another");
+                                       return result;
                                        }
 
-                                       if (new_locals != null)
-                                               locals.Or (new_locals);
+                               if (result.LocalVector != null)
+                                       locals.Or (result.LocalVector);
+
+                               if (result.ParameterVector != null)
+                                       parameters.Or (result.ParameterVector);
+
+                               Report.Debug (2, "  MERGING CHILD DONE", this, result);
+
+                               IsDirty = true;
 
-                                       if (new_params != null)
-                                               parameters.Or (new_params);
+                               return result;
                                }
 
-                               Report.Debug (2, "MERGING CHILD DONE", this);
+                       protected void MergeFinally (FlowBranching branching, UsageVector f_origins,
+                                                    MyBitVector f_params)
+                       {
+                               for (UsageVector vector = f_origins; vector != null; vector = vector.Next) {
+                                       MyBitVector temp_params = f_params.Clone ();
+                                       temp_params.Or (vector.Parameters);
+                               }
+                       }
+
+                       public void MergeFinally (FlowBranching branching, UsageVector f_vector,
+                                                 UsageVector f_origins)
+                       {
+                               if (parameters != null) {
+                                       if (f_vector != null) {
+                                               MergeFinally (branching, f_origins, f_vector.Parameters);
+                                               MyBitVector.Or (ref parameters, f_vector.ParameterVector);
+                                       } else
+                                               MergeFinally (branching, f_origins, parameters);
+                               }
 
-                               return Returns;
+                               if (f_vector != null)
+                                       MyBitVector.Or (ref locals, f_vector.LocalVector);
                        }
 
                        // <summary>
@@ -469,51 +673,55 @@ namespace Mono.CSharp
                        // </summary>
                        public void MergeJumpOrigins (ICollection origin_vectors)
                        {
-                               Report.Debug (1, "MERGING JUMP ORIGIN", this);
+                               Report.Debug (1, "  MERGING JUMP ORIGINS", this);
 
-                               RealBreaks = FlowReturns.Never;
-                               RealReturns = FlowReturns.Never;
-                               if (Reachable != FlowReturns.Always)
-                                       RealReachable = FlowReturns.Always;
+                               reachability = Reachability.Never ();
 
                                if (origin_vectors == null)
                                        return;
 
+                               bool first = true;
+
                                foreach (UsageVector vector in origin_vectors) {
                                        Report.Debug (1, "  MERGING JUMP ORIGIN", vector);
 
+                                       if (first) {
+                                               locals.Or (vector.locals);
+                                               if (parameters != null)
+                                                       parameters.Or (vector.parameters);
+                                               first = false;
+                                       } else {
                                        locals.And (vector.locals);
                                        if (parameters != null)
                                                parameters.And (vector.parameters);
-                                       RealBreaks = AndFlowReturns (RealBreaks, vector.Breaks);
-                                       RealReturns = AndFlowReturns (RealReturns, vector.Returns);
-                                       RealReachable = AndFlowReturns (RealReachable, vector.Reachable);
                                }
 
-                               Report.Debug (1, "MERGING JUMP ORIGIN DONE", this);
+                                       Reachability.And (ref reachability, vector.Reachability, true);
+                               }
+
+                               Report.Debug (1, "  MERGING JUMP ORIGINS DONE", this);
                        }
 
                        // <summary>
                        //   This is used at the beginning of a finally block if there were
                        //   any return statements in the try block or one of the catch blocks.
                        // </summary>
-                       public void MergeFinallyOrigins (ICollection finally_vectors)
+                       public void MergeFinallyOrigins (UsageVector f_origins)
                        {
-                               Report.Debug (1, "MERGING FINALLY ORIGIN", this);
+                               Report.Debug (1, "  MERGING FINALLY ORIGIN", this);
 
-                               RealBreaks = FlowReturns.Never;
+                               reachability = Reachability.Never ();
 
-                               foreach (UsageVector vector in finally_vectors) {
+                               for (UsageVector vector = f_origins; vector != null; vector = vector.Next) {
                                        Report.Debug (1, "  MERGING FINALLY ORIGIN", vector);
 
                                        if (parameters != null)
                                                parameters.And (vector.parameters);
-                                       RealBreaks = AndFlowReturns (Breaks, vector.Breaks);
-                               }
 
-                               is_finally = true;
+                                       Reachability.And (ref reachability, vector.Reachability, true);
+                               }
 
-                               Report.Debug (1, "MERGING FINALLY ORIGIN DONE", this);
+                               Report.Debug (1, "  MERGING FINALLY ORIGIN DONE", this);
                        }
 
                        public void CheckOutParameters (FlowBranching branching)
@@ -527,6 +735,7 @@ namespace Mono.CSharp
                        // </summary>
                        public void Or (UsageVector new_vector)
                        {
+                               IsDirty = true;
                                locals.Or (new_vector.locals);
                                if (parameters != null)
                                        parameters.Or (new_vector.parameters);
@@ -537,6 +746,7 @@ namespace Mono.CSharp
                        // </summary>
                        public void AndLocals (UsageVector new_vector)
                        {
+                               IsDirty = true;
                                locals.And (new_vector.locals);
                        }
 
@@ -596,11 +806,9 @@ namespace Mono.CSharp
                                sb.Append ("Vector (");
                                sb.Append (id);
                                sb.Append (",");
-                               sb.Append (Returns);
+                               sb.Append (IsDirty);
                                sb.Append (",");
-                               sb.Append (Breaks);
-                               sb.Append (",");
-                               sb.Append (Reachable);
+                               sb.Append (reachability);
                                if (parameters != null) {
                                        sb.Append (" - ");
                                        sb.Append (parameters);
@@ -655,15 +863,11 @@ namespace Mono.CSharp
                {
                        AddSibling (new UsageVector (type, Parent.CurrentUsageVector, Location));
 
-                       Report.Debug (1, "CREATED SIBLING", CurrentUsageVector);
+                       Report.Debug (1, "  CREATED SIBLING", CurrentUsageVector);
                }
 
                protected abstract void AddSibling (UsageVector uv);
 
-               public abstract void Break ();
-               public abstract void Return ();
-               public abstract void Goto ();
-               public abstract void Throw ();
                public abstract void Label (ArrayList origin_vectors);
 
                // <summary>
@@ -686,54 +890,27 @@ namespace Mono.CSharp
                        }
                }
 
-               protected class MergeResult
-               {
-                       public MyBitVector Parameters;
-                       public MyBitVector Locals;
-                       public FlowReturns Returns;
-                       public FlowReturns Breaks;
-                       public FlowReturns Reachable;
-                       public bool MayLeaveLoop;
-
-                       public MergeResult (MyBitVector parameters, MyBitVector locals, FlowReturns returns, FlowReturns breaks,
-                                           FlowReturns reachable, bool may_leave_loop)
+               protected UsageVector Merge (UsageVector sibling_list)
                        {
-                               this.Parameters = parameters;
-                               this.Locals = locals;
-                               this.Returns = returns;
-                               this.Breaks = breaks;
-                               this.Reachable = reachable;
-                               this.MayLeaveLoop = may_leave_loop;
-                       }
-               }
+                       if (sibling_list.Next == null)
+                               return sibling_list;
 
-               protected MergeResult Merge (ArrayList children)
-               {
                        MyBitVector locals = null;
                        MyBitVector parameters = null;
 
-                       FlowReturns returns = FlowReturns.Undefined;
-                       FlowReturns breaks = FlowReturns.Undefined;
-                       FlowReturns reachable = FlowReturns.Undefined;
+                       Reachability reachability = null;
 
-                       Report.Debug (2, "MERGING CHILDREN", this, Type, children.Count);
+                       Report.Debug (2, "  MERGING SIBLINGS", this, Name);
 
-                       int children_count = children.Count;
-                       for (int ix = 0; ix < children_count; ix++){
-                               UsageVector child = (UsageVector) children [ix];
+                       for (UsageVector child = sibling_list; child != null; child = child.Next) {
+                               bool do_break = (Type != BranchingType.Switch) &&
+                                       (Type != BranchingType.LoopBlock);
                                
-                               Report.Debug (2, "  MERGING CHILD", child, child.AlwaysBreaks, child.AlwaysReturns,
-                                             child.IsUnreachable, child.Locals, child.Parameters,
-                                             child.Returns, child.Breaks, child.Reachable);
-
-                               reachable = AndFlowReturns (reachable, child.Reachable);
-
-                               // Ignore unreachable children.
-                               if (child.IsUnreachable)
-                                       continue;
+                               Report.Debug (2, "    MERGING SIBLING   ", child,
+                                             child.Parameters, child.Locals,
+                                             reachability, child.Reachability, do_break);
 
-                               returns = AndFlowReturns (returns, child.Returns);
-                               breaks = AndFlowReturns (breaks, child.Breaks);
+                               Reachability.And (ref reachability, child.Reachability, do_break);
                                        
                                // A local variable is initialized after a flow branching if it
                                // has been initialized in all its branches which do neither
@@ -770,68 +947,51 @@ namespace Mono.CSharp
                                // Here, `a' is initialized in line 3 and we must not look at
                                // line 5 since it always returns.
                                // 
-                               if (!child.AlwaysReturns && !child.AlwaysBreaks)
+                               bool do_break_2 = (child.Type != SiblingType.Block) &&
+                                       (child.Type != SiblingType.SwitchSection);
+                               bool unreachable = (do_break_2 && child.Reachability.AlwaysBreaks) ||
+                                       child.Reachability.AlwaysThrows ||
+                                       child.Reachability.AlwaysReturns ||
+                                       child.Reachability.AlwaysHasBarrier;
+
+                               Report.Debug (2, "    MERGING SIBLING #1", reachability,
+                                             Type, child.Type, child.Reachability.IsUnreachable,
+                                             do_break_2, unreachable);
+
+                               if (!unreachable)
                                        MyBitVector.And (ref locals, child.LocalVector);
 
                                // An `out' parameter must be assigned in all branches which do
                                // not always throw an exception.
-                               if ((child.Type != SiblingType.Catch) &&
-                                   (child.ParameterVector != null) && (child.Breaks != FlowReturns.Exception))
+                               if ((child.ParameterVector != null) && !child.Reachability.AlwaysThrows)
                                        MyBitVector.And (ref parameters, child.ParameterVector);
-                       }
-
-                       Report.Debug (2, "MERGING CHILDREN DONE", Type, parameters, locals, returns, breaks, reachable,
-                                     Infinite, MayLeaveLoop, this);
 
-                       if (Infinite && !MayLeaveLoop) {
-                               Report.Debug (1, "INFINITE", returns, breaks, this);
-
-                               if (returns == FlowReturns.Never) {
-                                       // We're actually infinite.
-                                       breaks = FlowReturns.Unreachable;
-                                       returns = FlowReturns.Unreachable;
-                               } else if ((returns == FlowReturns.Sometimes) || (returns == FlowReturns.Always)) {
-                                       // If we're an infinite loop and do not break, the code after
-                                       // the loop can never be reached.  However, if we may return
-                                       // from the loop, then we do always return (or stay in the loop
-                                       // forever).
-                                       returns = FlowReturns.Always;
-                               }
+                               Report.Debug (2, "    MERGING SIBLING #2", parameters, locals);
                        }
 
-                       if (returns == FlowReturns.Undefined)
-                               returns = FlowReturns.Never;
-                       if (breaks == FlowReturns.Undefined)
-                               breaks = FlowReturns.Never;
+                       if (reachability == null)
+                               reachability = Reachability.Never ();
+
+                       Report.Debug (2, "  MERGING SIBLINGS DONE", parameters, locals,
+                                     reachability, Infinite);
 
-                       return new MergeResult (parameters, locals, returns, breaks, reachable, MayLeaveLoop);
+                       return new UsageVector (parameters, locals, reachability, Location);
                }
 
-               protected abstract MergeResult Merge ();
+               protected abstract UsageVector Merge ();
 
                // <summary>
                //   Merge a child branching.
                // </summary>
-               public FlowReturns MergeChild (FlowBranching child)
+               public UsageVector MergeChild (FlowBranching child)
                {
-                       MergeResult result = child.Merge ();
-
-                       CurrentUsageVector.MergeChild (
-                               result.Parameters, result.Locals, result.Returns, result.Breaks, result.Reachable);
-
-                       if ((child.Type != BranchingType.LoopBlock) && (child.Type != BranchingType.SwitchSection))
-                               MayLeaveLoop |= child.MayLeaveLoop;
-
-                       if (result.Reachable == FlowReturns.Exception)
-                               return FlowReturns.Exception;
-                       else
-                               return result.Returns;
+                       return CurrentUsageVector.MergeChild (child);
                }
 
                // <summary>
                //   Does the toplevel merging.
                // </summary>
-               public FlowReturns MergeTopBlock ()
+               public Reachability MergeTopBlock ()
                {
                        if ((Type != BranchingType.Block) || (Block == null))
                                throw new NotSupportedException ();
@@ -839,15 +999,14 @@ namespace Mono.CSharp
                        UsageVector vector = new UsageVector (
                                SiblingType.Conditional, null, Location, param_map.Length, local_map.Length);
 
-                       MergeResult result = Merge ();
-                       vector.MergeChild (result.Parameters, result.Locals, result.Returns, result.Breaks, result.Reachable);
+                       UsageVector result = vector.MergeChild (this);
 
-                       if (vector.Reachable != FlowReturns.Exception)
+                       Report.Debug (4, "MERGE TOP BLOCK", Location, vector, result.Reachability);
+
+                       if (vector.Reachability.Throws != FlowReturns.Always)
                                CheckOutParameters (vector.Parameters, Location);
-                       else
-                               return FlowReturns.Exception;
 
-                       return result.Returns;
+                       return result.Reachability;
                }
 
                public virtual bool InTryBlock ()
@@ -911,12 +1070,18 @@ namespace Mono.CSharp
                        sb.Append (")");
                        return sb.ToString ();
                }
+
+               public string Name {
+                       get {
+                               return String.Format ("{0} ({1}:{2}:{3})",
+                                                     GetType (), id, Type, Location);
+                       }
+               }
        }
 
        public class FlowBranchingBlock : FlowBranching
        {
-               UsageVector current_vector;
-               ArrayList siblings = new ArrayList ();
+               UsageVector sibling_list = null;
 
                public FlowBranchingBlock (FlowBranching parent, BranchingType type, SiblingType stype,
                                           Block block, Location loc)
@@ -924,81 +1089,53 @@ namespace Mono.CSharp
                { }
 
                public override UsageVector CurrentUsageVector {
-                       get { return current_vector; }
+                       get { return sibling_list; }
                }
 
                protected override void AddSibling (UsageVector sibling)
                {
-                       siblings.Add (sibling);
-                       current_vector = sibling;
-               }
-
-               public override void Break ()
-               {
-                       if (Type == BranchingType.SwitchSection)
-                               CurrentUsageVector.NeverReachable ();
-                       else {
-                               if (Type == BranchingType.LoopBlock)
-                                       MayLeaveLoop = true;
-                               CurrentUsageVector.Break ();
-                       }
-               }
-
-               public override void Return ()
-               {
-                       CurrentUsageVector.Return ();
-               }
-
-               public override void Goto ()
-               {
-                       CurrentUsageVector.Unreachable ();
+                       sibling.Next = sibling_list;
+                       sibling_list = sibling;
                }
 
-               public override void Throw ()
+               public override void Label (ArrayList origin_vectors)
                {
-                       CurrentUsageVector.Throw ();
+                       if (!CurrentUsageVector.Reachability.IsUnreachable) {
+                               if (origin_vectors == null)
+                                       origin_vectors = new ArrayList (1);
+                               origin_vectors.Add (CurrentUsageVector.Clone ());
                }
 
-               public override void Label (ArrayList origin_vectors)
-               {
                        CurrentUsageVector.MergeJumpOrigins (origin_vectors);
                }
 
-               protected override MergeResult Merge ()
+               protected override UsageVector Merge ()
                {
-                       MergeResult result = Merge (siblings);
-                       if (Type == BranchingType.LoopBlock)
-                               result.MayLeaveLoop = false;
-                       return result;
+                       return Merge (sibling_list);
                }
        }
 
        public class FlowBranchingException : FlowBranching
        {
-               ArrayList finally_vectors;
-
-               bool has_params;
                UsageVector current_vector;
-               UsageVector try_vector;
-               ArrayList catch_vectors = new ArrayList ();
+               UsageVector catch_vectors;
                UsageVector finally_vector;
+               UsageVector finally_origins;
 
                public FlowBranchingException (FlowBranching parent, BranchingType type, Block block, Location loc)
                        : base (parent, type, SiblingType.Try, block, loc)
-               {
-                       finally_vectors = new ArrayList ();
-                       has_params = current_vector.HasParameters;
-               }
+               { }
 
                protected override void AddSibling (UsageVector sibling)
                {
                        if (sibling.Type == SiblingType.Try) {
-                               try_vector = sibling;
-                               catch_vectors.Add (sibling);
-                       } else if (sibling.Type == SiblingType.Catch)
-                               catch_vectors.Add (sibling);
-                       else if (sibling.Type == SiblingType.Finally) {
-                               // sibling.MergeFinallyOrigins (finally_vectors);
+                               sibling.Next = catch_vectors;
+                               catch_vectors = sibling;
+                       } else if (sibling.Type == SiblingType.Catch) {
+                               sibling.Next = catch_vectors;
+                               catch_vectors = sibling;
+                       } else if (sibling.Type == SiblingType.Finally) {
+                               sibling.MergeFinallyOrigins (finally_origins);
                                finally_vector = sibling;
                        } else
                                throw new InvalidOperationException ();
@@ -1017,27 +1154,9 @@ namespace Mono.CSharp
 
                public override void AddFinallyVector (UsageVector vector)
                {
-                       finally_vectors.Add (vector.Clone ());
-               }
-
-               public override void Break ()
-               {
-                       CurrentUsageVector.Break ();
-               }
-
-               public override void Return ()
-               {
-                       CurrentUsageVector.Return ();
-               }
-
-               public override void Goto ()
-               {
-                       CurrentUsageVector.Unreachable ();
-               }
-
-               public override void Throw ()
-               {
-                       CurrentUsageVector.Throw ();
+                       vector = vector.Clone ();
+                       vector.Next = finally_origins;
+                       finally_origins = vector;
                }
 
                public override void Label (ArrayList origin_vectors)
@@ -1045,32 +1164,13 @@ namespace Mono.CSharp
                        CurrentUsageVector.MergeJumpOrigins (origin_vectors);
                }
 
-               protected void MergeFinally (MyBitVector f_params, ref MergeResult result)
-               {
-                       foreach (UsageVector vector in finally_vectors) {
-                               MyBitVector temp_params = f_params.Clone ();
-                               temp_params.Or (vector.Parameters);
-
-                               CheckOutParameters (temp_params, Location);
-                       }
-               }
-
-               protected override MergeResult Merge ()
+               protected override UsageVector Merge ()
                {
-                       MergeResult result = Merge (catch_vectors);
-
-                       if (has_params) {
-                               if (finally_vector != null) {
-                                       MergeFinally (finally_vector.Parameters, ref result);
-                                       MyBitVector.Or (ref result.Parameters, finally_vector.ParameterVector);
-                               } else
-                                       MergeFinally (result.Parameters, ref result);
-                       }
+                       UsageVector vector = Merge (catch_vectors);
 
-                       if (finally_vector != null)
-                               MyBitVector.Or (ref result.Locals, finally_vector.LocalVector);
+                       vector.MergeFinally (this, finally_vector, finally_origins);
 
-                       return result;
+                       return vector;
                }
        }
 
@@ -1878,20 +1978,16 @@ namespace Mono.CSharp
 
                public override string ToString ()
                {
-                       StringBuilder sb = new StringBuilder ("MyBitVector (");
+                       StringBuilder sb = new StringBuilder ("{");
 
                        BitArray vector = Vector;
-                       sb.Append (Count);
-                       sb.Append (",");
                        if (!IsDirty)
-                               sb.Append ("INHERITED - ");
+                               sb.Append ("=");
                        for (int i = 0; i < vector.Count; i++) {
-                               if (i > 0)
-                                       sb.Append (",");
-                               sb.Append (vector [i]);
+                               sb.Append (vector [i] ? "1" : "0");
                        }
                        
-                       sb.Append (")");
+                       sb.Append ("}");
                        return sb.ToString ();
                }
        }
index d7931355273075e4ea04c981f1d262a2b37e7767..a4dbf328ae9e54c6c4f9060128bc341fa0ad7ce2 100755 (executable)
@@ -448,12 +448,12 @@ namespace Generator {
                void GenerateFor (For s)
                {
                        output ("for (");
-                       if (! (s.InitStatement is EmptyStatement))
+                       if (! (s.InitStatement == EmptyStatement.Value))
                                GenerateStatement (s.InitStatement, true, true, true);
                        output ("; ");
                        output (GetExpression (s.Test, 0));
                        output ("; ");
-                       if (! (s.Increment is EmptyStatement))
+                       if (! (s.Increment == EmptyStatement.Value))
                                GenerateStatement (s.Increment, true, true, true);
                        output (") ");
                        GenerateStatement (s.Statement, true, true, false);
@@ -589,7 +589,7 @@ namespace Generator {
                                output_newline ("break;");
                        else if (s is Continue)
                                output_newline ("continue;");
-                       else if (s is EmptyStatement)
+                       else if (s == EmptyStatement.Value)
                                output_newline ("/* empty statement */;");
                        else if (s is Block)
                                GenerateBlock ((Block) s, doPlacement, embedded);
index 2f61dba38f7f7d8c2b3442dd900980605b7bdad6..adc5931629322335fdf3c18947d8cb8725cc962f 100755 (executable)
@@ -307,8 +307,6 @@ namespace Mono.CSharp {
                        
                        Type [] arg_types = im.ParameterTypes (this);
                        MethodBuilder mb;
-                       Parameter [] p;
-                       int i;
 
                        if (return_type == null)
                                return;
index a324bed8927cef89bd693dc9583f90de9ef0bb8f..5fc7523640efdd7ad50ccdea245bc9ac1e9d673a 100644 (file)
@@ -76,11 +76,9 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        IteratorHandler.Current.MarkYield (ec, expr);
-                       
-                       return false;
                }
        }
 
@@ -96,14 +94,13 @@ namespace Mono.CSharp {
                        if (!Yield.CheckContext (ec, loc))
                                return false;
 
-                       ec.CurrentBranching.Goto ();
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
                        return true;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        IteratorHandler.Current.EmitYieldBreak (ec.ig, true);
-                       return false;
                }
        }
 
index aeffec1a1d4f537c22a1657e073bcd6148d554b8..ea0eddc02471f00da505051d0d19af4d1b5eea33 100644 (file)
@@ -53,7 +53,6 @@ namespace Mono.CSharp {
                static int source_bits;
                static int source_mask;
                static int source_count;
-               static int module_base;
                static int current_source;
 
                public readonly static Location Null;
@@ -63,7 +62,6 @@ namespace Mono.CSharp {
                        source_files = new Hashtable ();
                        source_list = new ArrayList ();
                        current_source = 0;
-                       module_base = 0;
                        Null.token = 0;
                }
 
@@ -140,7 +138,6 @@ namespace Mono.CSharp {
                static public void Push (SourceFile file)
                {
                        current_source = file.Index;
-                       module_base = current_source << source_bits;
                }
 
                // <remarks>
index b6f8d42aef4b6b8d85508ac7b3c83ab1a26cc000..3c54199224949a5421bae0e2f09d2a7ec547366d 100755 (executable)
@@ -35,6 +35,8 @@ namespace Mono.CSharp {
 
                public const int Accessibility =
                        PUBLIC | PROTECTED | INTERNAL | PRIVATE;
+               public const int AllowedExplicitImplFlags =
+                       UNSAFE | EXTERN;
                
                static public string Name (int i)
                {
index 764d19c69d91133df6ed9d477b709f172ee5d985..a810e9aeddacbe3ddb98ac0b6a32393de344b122 100755 (executable)
@@ -19,7 +19,7 @@ namespace Mono.CSharp {
                static Hashtable namespaces_map = new Hashtable ();
                
                Namespace parent;
-               string name, fullname;
+               string fullname;
                ArrayList entries;
                Hashtable namespaces;
                Hashtable defined_names;
@@ -31,7 +31,6 @@ namespace Mono.CSharp {
                /// </summary>
                public Namespace (Namespace parent, string name)
                {
-                       this.name = name;
                        this.parent = parent;
 
                        string pname = parent != null ? parent.Name : "";
index 3867550c5b81396ea431aee679adacbddcda2e4c..2ffcbbfd1ed6debcca7e8de12c5f8dcb0dd84316 100644 (file)
@@ -13,6 +13,7 @@ using System;
 using System.Text;
 using System.Collections;
 using System.Diagnostics;
+using System.Reflection;
 
 namespace Mono.CSharp {
 
@@ -68,13 +69,55 @@ namespace Mono.CSharp {
                        }
                }
                
+               public static string FriendlyStackTrace (Exception e)
+               {
+                       return FriendlyStackTrace (new StackTrace (e, true));
+               }
+               
+               static string FriendlyStackTrace (StackTrace t)
+               {               
+                       StringBuilder sb = new StringBuilder ();
+                       
+                       bool foundUserCode = false;
+                       
+                       for (int i = 0; i < t.FrameCount; i++) {
+                               StackFrame f = t.GetFrame (i);
+                               MethodBase mb = f.GetMethod ();
+                               
+                               if (!foundUserCode && mb.ReflectedType == typeof (Report))
+                                       continue;
+                               
+                               foundUserCode = true;
+                               
+                               sb.Append ("\tin ");
+                               
+                               if (f.GetFileLineNumber () > 0)
+                                       sb.AppendFormat ("(at {0}:{1}) ", f.GetFileName (), f.GetFileLineNumber ());
+                               
+                               sb.AppendFormat ("{0}.{1} (", mb.ReflectedType.Name, mb.Name);
+                               
+                               bool first = true;
+                               foreach (ParameterInfo pi in mb.GetParameters ()) {
+                                       if (!first)
+                                               sb.Append (", ");
+                                       first = false;
+                                       
+                                       sb.Append (TypeManager.CSharpName (pi.ParameterType));
+                               }
+                               sb.Append (")\n");
+                       }
+       
+                       return sb.ToString ();
+               }
+               
                static public void RealError (string msg)
                {
                        Errors++;
                        Console.WriteLine (msg);
 
                        if (Stacktrace)
-                               Console.WriteLine (new StackTrace ().ToString ());
+                               Console.WriteLine (FriendlyStackTrace (new StackTrace (true)));
+                       
                        if (Fatal)
                                throw new Exception (msg);
                }
index d750422777284a54a87305afa4f6e244aec64a5d..73461961a48b222f43daba47aeb262a6ad6decd8 100755 (executable)
@@ -64,6 +64,9 @@ namespace Mono.CSharp {
 
                public static int WarningLevel = 2;
 
+               public static Target Target = Target.Exe;
+               public static string TargetExt = ".exe";
+
                //
                // If set, enable C# version 2 features
                //
@@ -78,6 +81,12 @@ namespace Mono.CSharp {
                        type_container_resolve_order = new ArrayList ();
                }
 
+               public static bool NeedsEntryPoint {
+                       get {
+                               return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe;
+                       }
+               }
+
                static public Tree Tree {
                        get {
                                return tree;
@@ -389,8 +398,6 @@ namespace Mono.CSharp {
                {
                        TypeContainer root = Tree.Types;
                        
-                       ArrayList ifaces = root.Interfaces;
-
                        if (root.Enums != null)
                                foreach (Enum en in root.Enums)
                                        en.CloseType ();
@@ -431,6 +438,13 @@ namespace Mono.CSharp {
                                foreach (TypeBuilder type_builder in helper_classes)
                                        type_builder.CreateType ();
                        }
+                       
+                       attribute_types = null;
+                       interface_resolve_order = null;
+                       type_container_resolve_order = null;
+                       helper_classes = null;
+                       tree = null;
+                       TypeManager.CleanUp ();
                }
 
                /// <summary>
@@ -461,8 +475,6 @@ namespace Mono.CSharp {
 
                static Type NamespaceLookup (DeclSpace ds, string name, Location loc)
                {
-                       Type t;
-
                        //
                        // Try in the current namespace and all its implicit parents
                        //
@@ -789,7 +801,6 @@ namespace Mono.CSharp {
                static public FieldBuilder MakeStaticData (byte [] data)
                {
                        FieldBuilder fb;
-                       int size = data.Length;
                        
                        if (impl_details_class == null){
                                impl_details_class = CodeGen.ModuleBuilder.DefineType (
index 9dd69704b00c938afd4bcbf6de3de99cc405166b..3a9b3a603fbb55c7b299a932c8dc9135c3fb196f 100755 (executable)
@@ -33,15 +33,15 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Return value indicates whether all code paths emitted return.
                /// </summary>
-               protected abstract bool DoEmit (EmitContext ec);
+               protected abstract void DoEmit (EmitContext ec);
 
                /// <summary>
                ///   Return value indicates whether all code paths emitted return.
                /// </summary>
-               public virtual bool Emit (EmitContext ec)
+               public virtual void Emit (EmitContext ec)
                {
                        ec.Mark (loc, true);
-                       return DoEmit (ec);
+                       DoEmit (ec);
                }
                
                /// <remarks>
@@ -106,9 +106,8 @@ namespace Mono.CSharp {
                        return true;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
-                       return true;
                }
        }
        
@@ -117,6 +116,8 @@ namespace Mono.CSharp {
                public Statement TrueStatement;
                public Statement FalseStatement;
                
+               bool is_true_ret;
+               
                public If (Expression expr, Statement trueStatement, Location l)
                {
                        this.expr = expr;
@@ -144,13 +145,15 @@ namespace Mono.CSharp {
                                return false;
                        }
                        
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
                        
                        if (!TrueStatement.Resolve (ec)) {
                                ec.KillFlowBranching ();
                                return false;
                        }
 
+                       is_true_ret = ec.CurrentBranching.CurrentUsageVector.Reachability.IsUnreachable;
+
                        ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Conditional);
 
                        if ((FalseStatement != null) && !FalseStatement.Resolve (ec)) {
@@ -165,12 +168,11 @@ namespace Mono.CSharp {
                        return true;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
                        Label false_target = ig.DefineLabel ();
                        Label end;
-                       bool is_true_ret, is_false_ret;
 
                        //
                        // Dead code elimination
@@ -182,18 +184,20 @@ namespace Mono.CSharp {
                                        if (FalseStatement != null){
                                                Warning_DeadCodeFound (FalseStatement.loc);
                                        }
-                                       return TrueStatement.Emit (ec);
+                                       TrueStatement.Emit (ec);
+                                       return;
                                } else {
                                        Warning_DeadCodeFound (TrueStatement.loc);
-                                       if (FalseStatement != null)
-                                               return FalseStatement.Emit (ec);
+                                       if (FalseStatement != null) {
+                                               FalseStatement.Emit (ec);
+                                               return;
+                                       }
                                }
                        }
                        
                        EmitBoolExpression (ec, expr, false_target, false);
 
-                       is_true_ret = TrueStatement.Emit (ec);
-                       is_false_ret = is_true_ret;
+                       TrueStatement.Emit (ec);
 
                        if (FalseStatement != null){
                                bool branch_emitted = false;
@@ -205,23 +209,20 @@ namespace Mono.CSharp {
                                }
 
                                ig.MarkLabel (false_target);
-                               is_false_ret = FalseStatement.Emit (ec);
+                               FalseStatement.Emit (ec);
 
                                if (branch_emitted)
                                        ig.MarkLabel (end);
                        } else {
                                ig.MarkLabel (false_target);
-                               is_false_ret = false;
                        }
-
-                       return is_true_ret && is_false_ret;
                }
        }
 
        public class Do : Statement {
                public Expression expr;
                public readonly Statement  EmbeddedStatement;
-               bool infinite, may_return;
+               bool infinite;
                
                public Do (Statement statement, Expression boolExpr, Location l)
                {
@@ -250,13 +251,12 @@ namespace Mono.CSharp {
                        }
 
                        ec.CurrentBranching.Infinite = infinite;
-                       FlowBranching.FlowReturns returns = ec.EndFlowBranching ();
-                       may_return = returns != FlowBranching.FlowReturns.Never;
+                       ec.EndFlowBranching ();
 
                        return ok;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
                        Label loop = ig.DefineLabel ();
@@ -291,18 +291,13 @@ namespace Mono.CSharp {
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                        ec.InLoop = old_inloop;
-
-                       if (infinite)
-                               return may_return == false;
-                       else
-                               return false;
                }
        }
 
        public class While : Statement {
                public Expression expr;
                public readonly Statement Statement;
-               bool may_return, empty, infinite;
+               bool empty, infinite;
                
                public While (Expression boolExpr, Statement statement, Location l)
                {
@@ -346,24 +341,22 @@ namespace Mono.CSharp {
                                ec.KillFlowBranching ();
                        else {
                                ec.CurrentBranching.Infinite = infinite;
-                               FlowBranching.FlowReturns returns = ec.EndFlowBranching ();
-                               may_return = returns != FlowBranching.FlowReturns.Never;
+                               ec.EndFlowBranching ();
                        }
 
                        return ok;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        if (empty)
-                               return false;
+                               return;
 
                        ILGenerator ig = ec.ig;
                        Label old_begin = ec.LoopBegin;
                        Label old_end = ec.LoopEnd;
                        bool old_inloop = ec.InLoop;
                        int old_loop_begin_try_catch_level = ec.LoopBeginTryCatchLevel;
-                       bool ret;
                        
                        ec.LoopBegin = ig.DefineLabel ();
                        ec.LoopEnd = ig.DefineLabel ();
@@ -374,8 +367,6 @@ namespace Mono.CSharp {
                        // Inform whether we are infinite or not
                        //
                        if (expr is BoolConstant){
-                               BoolConstant bc = (BoolConstant) expr;
-
                                ig.MarkLabel (ec.LoopBegin);
                                Statement.Emit (ec);
                                ig.Emit (OpCodes.Br, ec.LoopBegin);
@@ -384,7 +375,6 @@ namespace Mono.CSharp {
                                // Inform that we are infinite (ie, `we return'), only
                                // if we do not `break' inside the code.
                                //
-                               ret = may_return == false;
                                ig.MarkLabel (ec.LoopEnd);
                        } else {
                                Label while_loop = ig.DefineLabel ();
@@ -398,16 +388,12 @@ namespace Mono.CSharp {
 
                                EmitBoolExpression (ec, expr, while_loop, true);
                                ig.MarkLabel (ec.LoopEnd);
-
-                               ret = false;
                        }       
 
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                        ec.InLoop = old_inloop;
                        ec.LoopBeginTryCatchLevel = old_loop_begin_try_catch_level;
-
-                       return ret;
                }
        }
 
@@ -416,7 +402,7 @@ namespace Mono.CSharp {
                readonly Statement InitStatement;
                readonly Statement Increment;
                readonly Statement Statement;
-               bool may_return, infinite, empty;
+               bool infinite, empty;
                
                public For (Statement initStatement,
                            Expression test,
@@ -472,17 +458,16 @@ namespace Mono.CSharp {
                                ec.KillFlowBranching ();
                        else {
                                ec.CurrentBranching.Infinite = infinite;
-                               FlowBranching.FlowReturns returns = ec.EndFlowBranching ();
-                               may_return = returns != FlowBranching.FlowReturns.Never;
+                               ec.EndFlowBranching ();
                        }
 
                        return ok;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        if (empty)
-                               return false;
+                               return;
 
                        ILGenerator ig = ec.ig;
                        Label old_begin = ec.LoopBegin;
@@ -492,8 +477,7 @@ namespace Mono.CSharp {
                        Label loop = ig.DefineLabel ();
                        Label test = ig.DefineLabel ();
                        
-                       if (InitStatement != null)
-                               if (! (InitStatement is EmptyStatement))
+                       if (InitStatement != null && InitStatement != EmptyStatement.Value)
                                        InitStatement.Emit (ec);
 
                        ec.LoopBegin = ig.DefineLabel ();
@@ -506,7 +490,7 @@ namespace Mono.CSharp {
                        Statement.Emit (ec);
 
                        ig.MarkLabel (ec.LoopBegin);
-                       if (!(Increment is EmptyStatement))
+                       if (Increment != EmptyStatement.Value)
                                Increment.Emit (ec);
 
                        ig.MarkLabel (test);
@@ -531,20 +515,6 @@ namespace Mono.CSharp {
                        ec.LoopEnd = old_end;
                        ec.InLoop = old_inloop;
                        ec.LoopBeginTryCatchLevel = old_loop_begin_try_catch_level;
-                       
-                       //
-                       // Inform whether we are infinite or not
-                       //
-                       if (Test != null){
-                               if (Test is BoolConstant){
-                                       BoolConstant bc = (BoolConstant) Test;
-
-                                       if (bc.Value)
-                                               return may_return == false;
-                               }
-                               return false;
-                       } else
-                               return may_return == false;
                }
        }
        
@@ -563,13 +533,9 @@ namespace Mono.CSharp {
                        return expr != null;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
-                       ILGenerator ig = ec.ig;
-                       
                        expr.EmitStatement (ec);
-
-                       return false;
                }
 
                public override string ToString ()
@@ -610,28 +576,28 @@ namespace Mono.CSharp {
                        else
                                vector.CheckOutParameters (ec.CurrentBranching);
 
-                       ec.CurrentBranching.Return ();
+                       ec.CurrentBranching.CurrentUsageVector.Return ();
                        return true;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        if (ec.InFinally){
                                Report.Error (157, loc, "Control can not leave the body of the finally block");
-                               return false;
+                               return;
                        }
 
                        if (ec.ReturnType == null){
                                if (Expr != null){
                                        Report.Error (127, loc, "Return with a value not allowed here");
-                                       return true;
+                                       return;
                                }
                        } else {
                                if (Expr == null){
                                        Report.Error (126, loc, "An object of type `" +
                                                      TypeManager.CSharpName (ec.ReturnType) + "' is " +
                                                      "expected for the return statement");
-                                       return true;
+                                       return;
                                }
 
                                if (Expr.Type != ec.ReturnType)
@@ -639,7 +605,7 @@ namespace Mono.CSharp {
                                                ec, Expr, ec.ReturnType, loc);
 
                                if (Expr == null)
-                                       return true;
+                                       return;
 
                                Expr.Emit (ec);
 
@@ -657,8 +623,6 @@ namespace Mono.CSharp {
                                ec.ig.Emit (OpCodes.Ret);
                                ec.NeedExplicitReturn = false;
                        }
-
-                       return true; 
                }
        }
 
@@ -681,7 +645,7 @@ namespace Mono.CSharp {
                        if (!label.IsDefined)
                                label.AddUsageVector (ec.CurrentBranching.CurrentUsageVector);
 
-                       ec.CurrentBranching.Goto ();
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
 
                        return true;
                }
@@ -699,18 +663,15 @@ namespace Mono.CSharp {
                        }
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        Label l = label.LabelTarget (ec);
                        ec.ig.Emit (OpCodes.Br, l);
-                       
-                       return false;
                }
        }
 
        public class LabeledStatement : Statement {
                public readonly Location Location;
-               string label_name;
                bool defined;
                bool referenced;
                Label label;
@@ -719,7 +680,6 @@ namespace Mono.CSharp {
                
                public LabeledStatement (string label_name, Location l)
                {
-                       this.label_name = label_name;
                        this.Location = l;
                }
 
@@ -762,12 +722,10 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        LabelTarget (ec);
                        ec.ig.MarkLabel (label);
-
-                       return false;
                }
        }
        
@@ -784,23 +742,22 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       ec.CurrentBranching.Goto ();
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
                        return true;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        if (ec.Switch == null){
                                Report.Error (153, loc, "goto default is only valid in a switch statement");
-                               return false;
+                               return;
                        }
 
                        if (!ec.Switch.GotDefault){
                                Report.Error (159, loc, "No default target on switch statement");
-                               return false;
+                               return;
                        }
                        ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
-                       return false;
                }
        }
 
@@ -850,14 +807,13 @@ namespace Mono.CSharp {
 
                        label = sl.ILLabelCode;
 
-                       ec.CurrentBranching.Goto ();
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
                        return true;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        ec.ig.Emit (OpCodes.Br, label);
-                       return true;
                }
        }
        
@@ -897,11 +853,11 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       ec.CurrentBranching.Throw ();
+                       ec.CurrentBranching.CurrentUsageVector.Throw ();
                        return true;
                }
                        
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        if (expr == null){
                                if (ec.InCatch)
@@ -912,14 +868,12 @@ namespace Mono.CSharp {
                                                "A throw statement with no argument is only " +
                                                "allowed in a catch clause");
                                }
-                               return false;
+                               return;
                        }
 
                        expr.Emit (ec);
 
                        ec.ig.Emit (OpCodes.Throw);
-
-                       return true;
                }
        }
 
@@ -932,26 +886,23 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       ec.CurrentBranching.MayLeaveLoop = true;
-                       ec.CurrentBranching.Break ();
+                       ec.CurrentBranching.CurrentUsageVector.Break ();
                        return true;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
 
                        if (ec.InLoop == false && ec.Switch == null){
                                Report.Error (139, loc, "No enclosing loop or switch to continue to");
-                               return false;
+                               return;
                        }
 
                        if (ec.InTry || ec.InCatch)
                                ig.Emit (OpCodes.Leave, ec.LoopEnd);
                        else
                                ig.Emit (OpCodes.Br, ec.LoopEnd);
-
-                       return false;
                }
        }
 
@@ -964,17 +915,17 @@ namespace Mono.CSharp {
 
                public override bool Resolve (EmitContext ec)
                {
-                       ec.CurrentBranching.Goto ();
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
                        return true;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        Label begin = ec.LoopBegin;
                        
                        if (!ec.InLoop){
                                Report.Error (139, loc, "No enclosing loop to continue to");
-                               return false;
+                               return;
                        } 
 
                        //
@@ -994,7 +945,6 @@ namespace Mono.CSharp {
                                throw new Exception ("Should never happen");
                        else
                                ec.ig.Emit (OpCodes.Br, begin);
-                       return false;
                }
        }
 
@@ -1020,9 +970,8 @@ namespace Mono.CSharp {
 
                enum Flags : byte {
                        Used = 1,
-                       Assigned = 2,
-                       ReadOnly = 4,
-                       Fixed = 8
+                       ReadOnly = 2,
+                       Fixed = 4
                }
 
                Flags flags;
@@ -1053,6 +1002,14 @@ namespace Mono.CSharp {
                        return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, loc);
                }
 
+               public bool IsAssigned (EmitContext ec)
+               {
+                       if (VariableInfo == null)
+                               throw new Exception ();
+
+                       return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo);
+               }
+
                public bool Resolve (DeclSpace decl)
                {
                        if (VariableType == null)
@@ -1094,15 +1051,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool Assigned {
-                       get {
-                               return (flags & Flags.Assigned) != 0;
-                       }
-                       set {
-                               flags = value ? (flags | Flags.Assigned) : (flags & ~Flags.Assigned);
-                       }
-               }
-               
                public bool ReadOnly {
                        get {
                                return (flags & Flags.ReadOnly) != 0;
@@ -1404,6 +1352,7 @@ namespace Mono.CSharp {
                                variables = new Hashtable ();
 
                        this_variable = new LocalInfo (tc, this, l);
+                       this_variable.Used = true;
 
                        variables.Add ("this", this_variable);
 
@@ -1439,7 +1388,7 @@ namespace Mono.CSharp {
                        }
 
                        if (pars != null) {
-                               int idx = 0;
+                               int idx;
                                Parameter p = pars.GetParameterByName (name, out idx);
                                if (p != null) {
                                        Report.Error (136, l, "A local variable named `" + name + "' " +
@@ -1482,18 +1431,13 @@ namespace Mono.CSharp {
 
                public LocalInfo GetLocalInfo (string name)
                {
-                       if (variables != null) {
-                               object temp;
-                               temp = variables [name];
-
-                               if (temp != null){
-                                       return (LocalInfo) temp;
+                       for (Block b = this; b != null; b = b.Parent) {
+                               if (b.variables != null) {
+                                       LocalInfo ret = b.variables [name] as LocalInfo;
+                                       if (ret != null)
+                                               return ret;
                                }
                        }
-
-                       if (Parent != null)
-                               return Parent.GetLocalInfo (name);
-
                        return null;
                }
 
@@ -1509,17 +1453,13 @@ namespace Mono.CSharp {
 
                public Expression GetConstantExpression (string name)
                {
-                       if (constants != null) {
-                               object temp;
-                               temp = constants [name];
-                               
-                               if (temp != null)
-                                       return (Expression) temp;
+                       for (Block b = this; b != null; b = b.Parent) {
+                               if (b.constants != null) {
+                                       Expression ret = b.constants [name] as Expression;
+                                       if (ret != null)
+                                               return ret;
+                               }
                        }
-                       
-                       if (Parent != null)
-                               return Parent.GetConstantExpression (name);
-
                        return null;
                }
                
@@ -1547,10 +1487,10 @@ namespace Mono.CSharp {
                Parameters parameters = null;
                public Parameters Parameters {
                        get {
-                               if (Parent != null)
-                                       return Parent.Parameters;
-
-                               return parameters;
+                               Block b = this;
+                               while (b.Parent != null)
+                                       b = b.Parent;
+                               return b.parameters;
                        }
                }
 
@@ -1580,6 +1520,12 @@ namespace Mono.CSharp {
                        flags |= Flags.BlockUsed;
                }
 
+               public bool HasRet {
+                       get {
+                               return (flags & Flags.HasRet) != 0;
+                       }
+               }
+
                VariableMap param_map, local_map;
 
                public VariableMap ParameterMap {
@@ -1614,7 +1560,6 @@ namespace Mono.CSharp {
                /// </remarks>
                public void EmitMeta (EmitContext ec, InternalParameters ip)
                {
-                       DeclSpace ds = ec.DeclSpace;
                        ILGenerator ig = ec.ig;
 
                        //
@@ -1716,7 +1661,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void UsageWarning ()
+               void UsageWarning (FlowBranching.UsageVector vector)
                {
                        string name;
                        
@@ -1729,7 +1674,7 @@ namespace Mono.CSharp {
                                        
                                        name = (string) de.Key;
                                                
-                                       if (vi.Assigned){
+                                       if (vector.IsAssigned (vi.VariableInfo)){
                                                Report.Warning (
                                                        219, vi.Location, "The variable `" + name +
                                                        "' is assigned but its value is never used");
@@ -1741,10 +1686,6 @@ namespace Mono.CSharp {
                                        } 
                                }
                        }
-
-                       if (children != null)
-                               foreach (Block b in children)
-                                       b.UsageWarning ();
                }
 
                public override bool Resolve (EmitContext ec)
@@ -1752,12 +1693,13 @@ namespace Mono.CSharp {
                        Block prev_block = ec.CurrentBlock;
                        bool ok = true;
 
+                       int errors = Report.Errors;
+
                        ec.CurrentBlock = this;
                        ec.StartFlowBranching (this);
 
-                       Report.Debug (1, "RESOLVE BLOCK", StartLocation, ec.CurrentBranching);
+                       Report.Debug (4, "RESOLVE BLOCK", StartLocation, ec.CurrentBranching);
 
-                       ArrayList new_statements = new ArrayList ();
                        bool unreachable = false, warning_shown = false;
 
                        int statement_count = statements.Count;
@@ -1765,37 +1707,38 @@ namespace Mono.CSharp {
                                Statement s = (Statement) statements [ix];
                                
                                if (unreachable && !(s is LabeledStatement)) {
-                                       if (!warning_shown && !(s is EmptyStatement)) {
+                                       if (!warning_shown && s != EmptyStatement.Value) {
                                                warning_shown = true;
                                                Warning_DeadCodeFound (s.loc);
                                        }
 
+                                       statements [ix] = EmptyStatement.Value;
                                        continue;
                                }
 
                                if (s.Resolve (ec) == false) {
                                        ok = false;
+                                       statements [ix] = EmptyStatement.Value;
                                        continue;
                                }
 
                                if (s is LabeledStatement)
                                        unreachable = false;
                                else
-                                       unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable;
-
-                               new_statements.Add (s);
+                                       unreachable = ec.CurrentBranching.CurrentUsageVector.Reachability.IsUnreachable;
                        }
 
-                       statements = new_statements;
+                       Report.Debug (4, "RESOLVE BLOCK DONE", StartLocation, ec.CurrentBranching);
+
 
-                       Report.Debug (1, "RESOLVE BLOCK DONE", StartLocation, ec.CurrentBranching);
+                       FlowBranching.UsageVector vector = ec.DoEndFlowBranching ();
 
-                       FlowBranching.FlowReturns returns = ec.EndFlowBranching ();
                        ec.CurrentBlock = prev_block;
 
                        // 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 != FlowBranching.FlowReturns.Exception) &&
+                       if ((this_variable != null) &&
+                           (vector.Reachability.Throws != FlowBranching.FlowReturns.Always) &&
                            !this_variable.IsThisAssigned (ec, loc))
                                ok = false;
 
@@ -1806,28 +1749,31 @@ namespace Mono.CSharp {
                                                                "This label has not been referenced");
                        }
 
-                       Report.Debug (1, "RESOLVE BLOCK DONE #2", StartLocation, returns);
+                       Report.Debug (4, "RESOLVE BLOCK DONE #2", StartLocation, vector);
 
-                       if ((returns == FlowBranching.FlowReturns.Always) ||
-                           (returns == FlowBranching.FlowReturns.Exception) ||
-                           (returns == FlowBranching.FlowReturns.Unreachable))
+                       if ((vector.Reachability.Returns == FlowBranching.FlowReturns.Always) ||
+                           (vector.Reachability.Throws == FlowBranching.FlowReturns.Always) ||
+                           (vector.Reachability.Reachable == FlowBranching.FlowReturns.Never))
                                flags |= Flags.HasRet;
 
+                       if (ok && (errors == Report.Errors)) {
+                               if (RootContext.WarningLevel >= 3)
+                                       UsageWarning (vector);
+                       }
+
                        return ok;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        int statement_count = statements.Count;
                        for (int ix = 0; ix < statement_count; ix++){
                                Statement s = (Statement) statements [ix];
                                s.Emit (ec);
                        }
-
-                       return (flags & Flags.HasRet) != 0;
                }
 
-               public override bool Emit (EmitContext ec)
+               public override void Emit (EmitContext ec)
                {
                        Block prev_block = ec.CurrentBlock;
 
@@ -1854,15 +1800,13 @@ namespace Mono.CSharp {
                        }
 
                        ec.Mark (StartLocation, true);
-                       bool retval = DoEmit (ec);
+                       DoEmit (ec);
                        ec.Mark (EndLocation, true); 
 
                        if (emit_debug_info && is_lexical_block)
                                ec.ig.EndScope ();
 
                        ec.CurrentBlock = prev_block;
-
-                       return retval;
                }
        }
 
@@ -2294,7 +2238,7 @@ namespace Mono.CSharp {
                /// <param name="ec"></param>
                /// <param name="val"></param>
                /// <returns></returns>
-               bool TableSwitchEmit (EmitContext ec, LocalBuilder val)
+               void TableSwitchEmit (EmitContext ec, LocalBuilder val)
                {
                        int cElements = Elements.Count;
                        object [] rgKeys = new object [cElements];
@@ -2462,7 +2406,6 @@ namespace Mono.CSharp {
 
                        // now emit the code for the sections
                        bool fFoundDefault = false;
-                       bool fAllReturn = true;
                        foreach (SwitchSection ss in Sections)
                        {
                                foreach (SwitchLabel sl in ss.Labels)
@@ -2475,18 +2418,14 @@ namespace Mono.CSharp {
                                                fFoundDefault = true;
                                        }
                                }
-                               bool returns = ss.Block.Emit (ec);
-                               fAllReturn &= returns;
+                               ss.Block.Emit (ec);
                                //ig.Emit (OpCodes.Br, lblEnd);
                        }
                        
                        if (!fFoundDefault) {
                                ig.MarkLabel (lblDefault);
-                               fAllReturn = false;
                        }
                        ig.MarkLabel (lblEnd);
-
-                       return fAllReturn;
                }
                //
                // This simple emit switch works, but does not take advantage of the
@@ -2494,7 +2433,7 @@ namespace Mono.CSharp {
                // TODO: remove non-string logic from here
                // TODO: binary search strings?
                //
-               bool SimpleSwitchEmit (EmitContext ec, LocalBuilder val)
+               void SimpleSwitchEmit (EmitContext ec, LocalBuilder val)
                {
                        ILGenerator ig = ec.ig;
                        Label end_of_switch = ig.DefineLabel ();
@@ -2503,7 +2442,6 @@ namespace Mono.CSharp {
                        bool default_found = false;
                        bool first_test = true;
                        bool pending_goto_end = false;
-                       bool all_return = true;
                        bool null_found;
                        
                        ig.Emit (OpCodes.Ldloc, val);
@@ -2571,23 +2509,15 @@ namespace Mono.CSharp {
                                foreach (SwitchLabel sl in ss.Labels)
                                        ig.MarkLabel (sl.ILLabelCode);
 
-                               bool returns = ss.Block.Emit (ec);
-                               if (returns)
-                                       pending_goto_end = false;
-                               else {
-                                       all_return = false;
-                                       pending_goto_end = true;
-                               }
+                               ss.Block.Emit (ec);
+                               pending_goto_end = !ss.Block.HasRet;
                                first_test = false;
                        }
                        if (!default_found){
                                ig.MarkLabel (default_target);
-                               all_return = false;
                        }
                        ig.MarkLabel (next_test);
                        ig.MarkLabel (end_of_switch);
-
-                       return all_return;
                }
 
                public override bool Resolve (EmitContext ec)
@@ -2635,7 +2565,7 @@ namespace Mono.CSharp {
                        return true;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        // Store variable for comparission purposes
                        LocalBuilder value = ec.ig.DeclareLocal (SwitchType);
@@ -2656,11 +2586,10 @@ namespace Mono.CSharp {
                        ec.Switch = this;
 
                        // Emit Code.
-                       bool all_return;
                        if (SwitchType == TypeManager.string_type)
-                               all_return = SimpleSwitchEmit (ec, value);
+                               SimpleSwitchEmit (ec, value);
                        else
-                               all_return = TableSwitchEmit (ec, value);
+                               TableSwitchEmit (ec, value);
 
                        // Restore context state. 
                        ig.MarkLabel (ec.LoopEnd);
@@ -2670,8 +2599,6 @@ namespace Mono.CSharp {
                        //
                        ec.LoopEnd = old_end;
                        ec.Switch = old_switch;
-                       
-                       return all_return;
                }
        }
 
@@ -2692,16 +2619,15 @@ namespace Mono.CSharp {
                        return Statement.Resolve (ec) && expr != null;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        Type type = expr.Type;
-                       bool val;
                        
                        if (type.IsValueType){
                                Report.Error (185, loc, "lock statement requires the expression to be " +
                                              " a reference type (type is: `" +
                                              TypeManager.CSharpName (type) + "'");
-                               return false;
+                               return;
                        }
 
                        ILGenerator ig = ec.ig;
@@ -2713,11 +2639,11 @@ namespace Mono.CSharp {
                        ig.Emit (OpCodes.Call, TypeManager.void_monitor_enter_object);
 
                        // try
-                       Label end = ig.BeginExceptionBlock ();
+                       ig.BeginExceptionBlock ();
                        bool old_in_try = ec.InTry;
                        ec.InTry = true;
                        Label finish = ig.DefineLabel ();
-                       val = Statement.Emit (ec);
+                       Statement.Emit (ec);
                        ec.InTry = old_in_try;
                        // ig.Emit (OpCodes.Leave, finish);
 
@@ -2728,8 +2654,6 @@ namespace Mono.CSharp {
                        ig.Emit (OpCodes.Ldloc, temp);
                        ig.Emit (OpCodes.Call, TypeManager.void_monitor_exit_object);
                        ig.EndExceptionBlock ();
-                       
-                       return val;
                }
        }
 
@@ -2756,19 +2680,16 @@ namespace Mono.CSharp {
                        return ret;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        bool previous_state = ec.CheckState;
                        bool previous_state_const = ec.ConstantCheckState;
-                       bool val;
                        
                        ec.CheckState = false;
                        ec.ConstantCheckState = false;
-                       val = Block.Emit (ec);
+                       Block.Emit (ec);
                        ec.CheckState = previous_state;
                        ec.ConstantCheckState = previous_state_const;
-
-                       return val;
                }
        }
 
@@ -2795,19 +2716,16 @@ namespace Mono.CSharp {
                        return ret;
                }
 
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        bool previous_state = ec.CheckState;
                        bool previous_state_const = ec.ConstantCheckState;
-                       bool val;
                        
                        ec.CheckState = true;
                        ec.ConstantCheckState = true;
-                       val = Block.Emit (ec);
+                       Block.Emit (ec);
                        ec.CheckState = previous_state;
                        ec.ConstantCheckState = previous_state_const;
-
-                       return val;
                }
        }
 
@@ -2831,16 +2749,13 @@ namespace Mono.CSharp {
                        return val;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        bool previous_state = ec.InUnsafe;
-                       bool val;
                        
                        ec.InUnsafe = true;
-                       val = Block.Emit (ec);
+                       Block.Emit (ec);
                        ec.InUnsafe = previous_state;
-
-                       return val;
                }
        }
 
@@ -2853,6 +2768,7 @@ namespace Mono.CSharp {
                Statement statement;
                Type expr_type;
                FixedData[] data;
+               bool has_ret;
 
                struct FixedData {
                        public bool is_object;
@@ -2998,14 +2914,23 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       return statement.Resolve (ec);
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
+
+                       if (!statement.Resolve (ec)) {
+                               ec.KillFlowBranching ();
+                               return false;
+                       }
+
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
+                       has_ret = reachability.IsUnreachable;
+
+                       return true;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
 
-                       bool is_ret = false;
                        LocalBuilder [] clear_list = new LocalBuilder [data.Length];
                        
                        for (int i = 0; i < data.Length; i++) {
@@ -3061,16 +2986,15 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       is_ret = statement.Emit (ec);
+                       statement.Emit (ec);
+
+                       if (has_ret)
+                               return;
 
-                       if (is_ret)
-                               return is_ret;
                        //
                        // Clear the pinned variable
                        //
                        for (int i = 0; i < data.Length; i++) {
-                               LocalInfo vi = data [i].vi;
-
                                if (data [i].is_object || data [i].expr.Type.IsArray) {
                                        ig.Emit (OpCodes.Ldc_I4_0);
                                        ig.Emit (OpCodes.Conv_U);
@@ -3080,8 +3004,6 @@ namespace Mono.CSharp {
                                        ig.Emit (OpCodes.Stloc, clear_list [i]);
                                }
                        }
-
-                       return is_ret;
                }
        }
        
@@ -3229,13 +3151,13 @@ namespace Mono.CSharp {
                                ec.InFinally = old_in_finally;
                        }
 
-                       FlowBranching.FlowReturns returns = ec.EndFlowBranching ();
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
 
                        FlowBranching.UsageVector f_vector = ec.CurrentBranching.CurrentUsageVector;
 
-                       Report.Debug (1, "END OF TRY", ec.CurrentBranching, returns, vector, f_vector);
+                       Report.Debug (1, "END OF TRY", ec.CurrentBranching, reachability, vector, f_vector);
 
-                       if (returns != FlowBranching.FlowReturns.Always) {
+                       if (reachability.Returns != FlowBranching.FlowReturns.Always) {
                                // 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.
@@ -3246,18 +3168,16 @@ namespace Mono.CSharp {
                        return ok;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
-                       Label end;
                        Label finish = ig.DefineLabel ();;
-                       bool returns;
 
                        ec.TryCatchLevel++;
-                       end = ig.BeginExceptionBlock ();
+                       ig.BeginExceptionBlock ();
                        bool old_in_try = ec.InTry;
                        ec.InTry = true;
-                       returns = Block.Emit (ec);
+                       Block.Emit (ec);
                        ec.InTry = old_in_try;
 
                        //
@@ -3266,7 +3186,6 @@ namespace Mono.CSharp {
 
                        bool old_in_catch = ec.InCatch;
                        ec.InCatch = true;
-                       DeclSpace ds = ec.DeclSpace;
 
                        foreach (Catch c in Specific){
                                LocalInfo vi;
@@ -3282,15 +3201,13 @@ namespace Mono.CSharp {
                                } else
                                        ig.Emit (OpCodes.Pop);
                                
-                               if (!c.Block.Emit (ec))
-                                       returns = false;
+                               c.Block.Emit (ec);
                        }
 
                        if (General != null){
                                ig.BeginCatchBlock (TypeManager.object_type);
                                ig.Emit (OpCodes.Pop);
-                               if (!General.Block.Emit (ec))
-                                       returns = false;
+                               General.Block.Emit (ec);
                        }
                        ec.InCatch = old_in_catch;
 
@@ -3305,8 +3222,6 @@ namespace Mono.CSharp {
                        
                        ig.EndExceptionBlock ();
                        ec.TryCatchLevel--;
-
-                       return returns;
                }
        }
 
@@ -3500,9 +3415,9 @@ namespace Mono.CSharp {
                                return false;
                        }
                                        
-                       FlowBranching.FlowReturns returns = ec.EndFlowBranching ();
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
 
-                       if (returns != FlowBranching.FlowReturns.Always) {
+                       if (reachability.Returns != FlowBranching.FlowReturns.Always) {
                                // 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.
@@ -3513,14 +3428,12 @@ namespace Mono.CSharp {
                        return true;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
                        if (expression_or_block is DictionaryEntry)
-                               return EmitLocalVariableDecls (ec);
+                               EmitLocalVariableDecls (ec);
                        else if (expression_or_block is Expression)
-                               return EmitExpression (ec);
-
-                       return false;
+                               EmitExpression (ec);
                }
        }
 
@@ -3610,7 +3523,7 @@ namespace Mono.CSharp {
                        if (!statement.Resolve (ec))
                                return false;
 
-                       FlowBranching.FlowReturns returns = ec.EndFlowBranching ();
+                       ec.EndFlowBranching ();
 
                        return true;
                }
@@ -3898,11 +3811,10 @@ namespace Mono.CSharp {
                        // Protect the code in a try/finalize block, so that
                        // if the beast implement IDisposable, we get rid of it
                        //
-                       Label l;
                        bool old_in_try = ec.InTry;
 
                        if (hm.is_disposable) {
-                               l = ig.BeginExceptionBlock ();
+                               ig.BeginExceptionBlock ();
                                ec.InTry = true;
                        }
                        
@@ -4117,10 +4029,8 @@ namespace Mono.CSharp {
                        return false;
                }
                
-               protected override bool DoEmit (EmitContext ec)
+               protected override void DoEmit (EmitContext ec)
                {
-                       bool ret_val;
-                       
                        ILGenerator ig = ec.ig;
                        
                        Label old_begin = ec.LoopBegin, old_end = ec.LoopEnd;
@@ -4132,16 +4042,14 @@ namespace Mono.CSharp {
                        ec.LoopBeginTryCatchLevel = ec.TryCatchLevel;
                        
                        if (hm != null)
-                               ret_val = EmitCollectionForeach (ec);
+                               EmitCollectionForeach (ec);
                        else
-                               ret_val = EmitArrayForeach (ec);
+                               EmitArrayForeach (ec);
                        
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                        ec.InLoop = old_inloop;
                        ec.LoopBeginTryCatchLevel = old_loop_begin_try_catch_level;
-
-                       return ret_val;
                }
        }
 }
index a40d4607b9490fd24d8282310330791e157ce565..5315fcf7b9951fed1a703bfdf12dc51422ab6e66 100755 (executable)
@@ -206,7 +206,11 @@ namespace Mono.CSharp {
        }
 
        class PtrHashtable : Hashtable {
-               class PtrComparer : IComparer {
+               sealed class PtrComparer : IComparer {
+                       private PtrComparer () {}
+                       
+                       public static PtrComparer Instance = new PtrComparer ();
+                       
                        public int Compare (object x, object y)
                        {
                                if (x == y)
@@ -218,7 +222,50 @@ namespace Mono.CSharp {
                
                public PtrHashtable ()
                {
-                       comparer = new PtrComparer ();
+                       comparer = PtrComparer.Instance;
+               }
+       }
+
+       /*
+        * Hashtable whose keys are character arrays with the same length
+        */
+       class CharArrayHashtable : Hashtable {
+               sealed class ArrComparer : IComparer {
+                       private int len;
+
+                       public ArrComparer (int len) {
+                               this.len = len;
+                       }
+
+                       public int Compare (object x, object y)
+                       {
+                               char[] a = (char[])x;
+                               char[] b = (char[])y;
+
+                               for (int i = 0; i < len; ++i)
+                                       if (a [i] != b [i])
+                                               return 1;
+                               return 0;
+                       }
+               }
+
+               private int len;
+
+               protected override int GetHash (Object key)
+               {
+                       char[] arr = (char[])key;
+                       int h = 0;
+
+                       for (int i = 0; i < len; ++i)
+                               h = (h << 5) - h + arr [i];
+
+                       return h;
+               }
+
+               public CharArrayHashtable (int len)
+               {
+                       this.len = len;
+                       comparer = new ArrComparer (len);
                }
        }
 
@@ -330,23 +377,46 @@ namespace Mono.CSharp {
        }
 
        public class DoubleHash {
-               Hashtable l = new Hashtable ();
+               const int DEFAULT_INITIAL_BUCKETS = 100;
                
-               public DoubleHash ()
+               public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS) {}
+               
+               public DoubleHash (int size)
                {
+                       count = size;
+                       buckets = new Entry [size];
+               }
+               
+               int count;
+               Entry [] buckets;
+               int size = 0;
+               
+               class Entry {
+                       public object key1;
+                       public object key2;
+                       public int hash;
+                       public object value;
+                       public Entry next;
+       
+                       public Entry (object key1, object key2, int hash, object value, Entry next)
+                       {
+                               this.key1 = key1;
+                               this.key2 = key2;
+                               this.hash = hash;
+                               this.next = next;
+                               this.value = value;
+                       }
                }
 
                public bool Lookup (object a, object b, out object res)
                {
-                       object r = l [a];
-                       if (r == null){
-                               res = null;
-                               return false;
+                       int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
+                       
+                       for (Entry e = buckets [h % count]; e != null; e = e.next) {
+                               if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b)) {
+                                       res = e.value;
+                                       return true;
                        }
-                       Hashtable ht = (Hashtable) r;
-                       if (ht.Contains (b)){
-                               res = ht [b];
-                               return true;
                        }
                        res = null;
                        return false;
@@ -354,16 +424,37 @@ namespace Mono.CSharp {
 
                public void Insert (object a, object b, object value)
                {
-                       Hashtable ht;
-                       object r = l [a];
-                       if (r == null){
-                               ht = new Hashtable ();
-                               l [a] = ht;
-                               ht [b] = value;
-                               return;
+                       // Is it an existing one?
+               
+                       int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
+                       
+                       for (Entry e = buckets [h % count]; e != null; e = e.next) {
+                               if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b))
+                                       e.value = value;
+                       }
+                       
+                       int bucket = h % count;
+                       buckets [bucket] = new Entry (a, b, h, value, buckets [bucket]);
+                       
+                       // Grow whenever we double in size
+                       if (size++ == count) {
+                               count <<= 1;
+                               count ++;
+                               
+                               Entry [] newBuckets = new Entry [count];
+                               foreach (Entry root in buckets) {
+                                       Entry e = root;
+                                       while (e != null) {
+                                               int newLoc = e.hash % count;
+                                               Entry n = e.next;
+                                               e.next = newBuckets [newLoc];
+                                               newBuckets [newLoc] = e;
+                                               e = n;
+                                       }
+                               }
+
+                               buckets = newBuckets;
                        }
-                       ht = (Hashtable) r;
-                       ht [b] = value;
                }
        }
 }
index c7eb289fd05aaf707137fa876161868a9249c0b0..f5b51016dd8fefee74797dc8ab5baf0010a4cdee 100755 (executable)
@@ -175,10 +175,10 @@ public class TypeManager {
        static Assembly [] assemblies;
 
        // <remarks>
-       //  Keeps a list of module builders. We used this to do lookups
-       //  on the modulebuilder using GetType -- needed for arrays
+       //  Keeps a list of modules. We used this to do lookups
+       //  on the module using GetType -- needed for arrays
        // </remarks>
-       static ModuleBuilder [] modules;
+       static Module [] modules;
 
        // <remarks>
        //   This is the type_cache from the assemblies to avoid
@@ -241,6 +241,35 @@ public class TypeManager {
                public Type [] args;
        }
 
+       public static void CleanUp ()
+       {
+               // Lets get everything clean so that we can collect before generating code
+               assemblies = null;
+               modules = null;
+               types = null;
+               typecontainers = null;
+               user_types = null;
+               builder_to_declspace = null;
+               builder_to_ifaces = null;
+               method_arguments = null;
+               indexer_arguments = null;
+               method_internal_params = null;
+               builder_to_attr = null;
+               builder_to_method = null;
+               
+               fields = null;
+               references = null;
+               negative_hits = null;
+               attr_to_allowmult = null;
+               builder_to_constant = null;
+               fieldbuilders_to_fields = null;
+               events = null;
+               priv_fields_events = null;
+               properties = null;
+               
+               TypeHandle.CleanUp ();
+       }
+
        /// <summary>
        ///   A filter for Findmembers that uses the Signature object to
        ///   extract objects
@@ -348,7 +377,6 @@ public class TypeManager {
                        return;
                }
                
-               Location l;
                tc = builder_to_declspace [t] as TypeContainer;
                if (tc != null){
                        Report.Warning (
@@ -497,10 +525,10 @@ public class TypeManager {
        /// <summary>
        ///  Registers a module builder to lookup types from
        /// </summary>
-       public static void AddModule (ModuleBuilder mb)
+       public static void AddModule (Module mb)
        {
                int top = modules != null ? modules.Length : 0;
-               ModuleBuilder [] n = new ModuleBuilder [top + 1];
+               Module [] n = new Module [top + 1];
 
                if (modules != null)
                        modules.CopyTo (n, 0);
@@ -578,7 +606,7 @@ public class TypeManager {
                        } while (t != null);
                }
 
-               foreach (ModuleBuilder mb in modules) {
+               foreach (Module mb in modules) {
                        t = mb.GetType (name);
                        if (t != null) 
                                return t;
@@ -611,6 +639,8 @@ public class TypeManager {
                return t;
        }
 
+       static readonly char [] dot_array = { '.' };
+
        /// <summary>
        ///   Returns the Type associated with @name, takes care of the fact that
        ///   reflection expects nested types to be separated from the main type
@@ -632,7 +662,8 @@ public class TypeManager {
                if (negative_hits.Contains (name))
                        return null;
 
-               string [] elements = name.Split ('.');
+               // Sadly, split takes a param array, so this ends up allocating *EVERY TIME*
+               string [] elements = name.Split (dot_array);
                int count = elements.Length;
 
                for (int n = 1; n <= count; n++){
@@ -646,7 +677,7 @@ public class TypeManager {
                        if (t == null){
                                t = LookupTypeReflection (top_level_type);
                                if (t == null){
-                                       negative_hits [top_level_type] = true;
+                                       negative_hits [top_level_type] = null;
                                        continue;
                                }
                        }
@@ -667,12 +698,12 @@ public class TypeManager {
                        //Console.WriteLine ("Looking up: " + newt + " " + name);
                        t = LookupTypeReflection (newt);
                        if (t == null)
-                               negative_hits [name] = true;
+                               negative_hits [name] = null;
                        else
                                types [name] = t;
                        return t;
                }
-               negative_hits [name] = true;
+               negative_hits [name] = null;
                return null;
        }
 
@@ -688,7 +719,6 @@ public class TypeManager {
                //
                if (assembly_get_namespaces != null){
                        int count = assemblies.Length;
-                       int total;
 
                        for (int i = 0; i < count; i++){
                                Assembly a = assemblies [i];
@@ -800,16 +830,19 @@ public class TypeManager {
        ///   Returns the MethodInfo for a method named `name' defined
        ///   in type `t' which takes arguments of types `args'
        /// </summary>
-       static MethodInfo GetMethod (Type t, string name, Type [] args, bool report_errors)
+       static MethodInfo GetMethod (Type t, string name, Type [] args, bool is_private, bool report_errors)
        {
                MemberList list;
                Signature sig;
+               BindingFlags flags = instance_and_static | BindingFlags.Public;
 
                sig.name = name;
                sig.args = args;
                
-               list = FindMembers (t, MemberTypes.Method, instance_and_static | BindingFlags.Public,
-                                   signature_filter, sig);
+               if (is_private)
+                       flags |= BindingFlags.NonPublic;
+
+               list = FindMembers (t, MemberTypes.Method, flags, signature_filter, sig);
                if (list.Count == 0) {
                        if (report_errors)
                                Report.Error (-19, "Can not find the core function `" + name + "'");
@@ -826,6 +859,11 @@ public class TypeManager {
                return mi;
        }
 
+       static MethodInfo GetMethod (Type t, string name, Type [] args, bool report_errors)
+       {
+               return GetMethod (t, name, args, false, report_errors);
+       }
+
        static MethodInfo GetMethod (Type t, string name, Type [] args)
        {
                return GetMethod (t, name, args, true);
@@ -979,7 +1017,7 @@ public class TypeManager {
 
                        MethodInfo set_corlib_type_builders = GetMethod (
                                system_assemblybuilder_type, "SetCorlibTypeBuilders",
-                               system_4_type_arg, false);
+                               system_4_type_arg, true, false);
 
                        if (set_corlib_type_builders != null) {
                                object[] args = new object [4];
@@ -993,7 +1031,7 @@ public class TypeManager {
                                // Compatibility for an older version of the class libs.
                                set_corlib_type_builders = GetMethod (
                                        system_assemblybuilder_type, "SetCorlibTypeBuilders",
-                                       system_3_type_arg, true);
+                                       system_3_type_arg, true, true);
 
                                if (set_corlib_type_builders == null) {
                                        Report.Error (-26, "Corlib compilation is not supported in Microsoft.NET due to bugs in it");
@@ -1158,8 +1196,6 @@ public class TypeManager {
 
        const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
 
-       static Hashtable type_hash = new Hashtable ();
-
        /// <remarks>
        ///   This is the "old", non-cache based FindMembers() function.  We cannot use
        ///   the cache here because there is no member name argument.
@@ -1235,8 +1271,6 @@ public class TypeManager {
        private static MemberList MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
                                                            string name, out bool used_cache)
        {
-                bool not_loaded_corlib = (t.Assembly == CodeGen.AssemblyBuilder);
-                
                //
                // We have to take care of arrays specially, because GetType on
                // a TypeBuilder array will return a Type, not a TypeBuilder,
@@ -2258,11 +2292,6 @@ public class TypeManager {
        
 #region MemberLookup implementation
        
-       //
-       // Name of the member
-       //
-       static string   closure_name;
-
        //
        // Whether we allow private members in the result (since FindMembers
        // uses NonPublic for both protected and private), we need to distinguish.
@@ -2273,7 +2302,6 @@ public class TypeManager {
        // Who is invoking us and which type is being queried currently.
        //
        static Type     closure_invocation_type;
-       static Type     closure_queried_type;
        static Type     closure_qualifier_type;
 
        //
@@ -2470,7 +2498,6 @@ public class TypeManager {
                bool skip_iface_check = true, used_cache = false;
                bool always_ok_flag = false;
 
-               closure_name = name;
                closure_invocation_type = invocation_type;
                closure_invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
                closure_qualifier_type = qualifier_type;
@@ -2515,7 +2542,6 @@ public class TypeManager {
                                bf = original_bf;
 
                        closure_private_ok = (original_bf & BindingFlags.NonPublic) != 0;
-                       closure_queried_type = current_type;
 
                        Timer.StopTimer (TimerType.MemberLookup);
 
@@ -2735,6 +2761,11 @@ public sealed class TypeHandle : IMemberContainer {
                type_hash.Add (t, handle);
                return handle;
        }
+       
+       public static void CleanUp ()
+       {
+               type_hash = null;
+       }
 
        /// <summary>
        ///   Returns the TypeHandle for TypeManager.object_type.