**** Merged from MCS ****
authorMartin Baulig <martin@novell.com>
Wed, 19 May 2004 13:05:18 +0000 (13:05 -0000)
committerMartin Baulig <martin@novell.com>
Wed, 19 May 2004 13:05:18 +0000 (13:05 -0000)
svn path=/trunk/mcs/; revision=27670

mcs/gmcs/ChangeLog
mcs/gmcs/cfold.cs
mcs/gmcs/const.cs
mcs/gmcs/constant.cs
mcs/gmcs/driver.cs
mcs/gmcs/ecore.cs
mcs/gmcs/expression.cs
mcs/gmcs/flowanalysis.cs
mcs/gmcs/rootcontext.cs
mcs/gmcs/statement.cs
mcs/gmcs/typemanager.cs

index f29c3c4a354c147a28d18c001a9be7a3268566b9..c7cc4ec292da94d76b42e038465b2a3d3b55d65c 100755 (executable)
@@ -1,3 +1,86 @@
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Block.LookupLabel): Also lookup in implicit child blocks.
+       (Block.AddLabel): Call DoLookupLabel() to only search in the
+       current block.
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * cfold.cs (ConstantFold.BinaryFold): Added special support for
+       comparing StringConstants and NullLiterals in Equality and Inequality.
+
+2004-04-28  Jackson Harper  <jackson@ximian.com>
+
+       * driver.cs: Attempt to load referenced assemblies from the
+       GAC. This is the quick and dirty version of this method that
+       doesnt take into account versions and just takes the first
+       canidate found. Will be good enough for now as we will not have more
+       then one version installed into the GAC until I update this method.
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.CheckStructCycles): New public
+       static method to check for cycles in the struct layout.
+
+       * rootcontext.cs (RootContext.PopulateTypes): Call
+       TypeManager.CheckStructCycles() for each TypeContainer.
+       [Note: We only need to visit each type once.]
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * constant.cs (StringConstant.Emit): Emit Ldnull if we're null.
+
+       * const.cs (Const.LookupConstantValue): Return a `bool' signalling
+       success and added `out object value'.  Use a `bool resolved' field
+       to check whether we've already been called rather than
+       `ConstantValue != null' since this breaks for NullLiterals.
+
+2004-04-28  Raja R Harinath  <rharinath@novell.com>
+
+       * driver.cs (Driver.MainDriver) [IsModuleOnly]: Open code the
+       setting of this flag, since the 'set' method may be non-public.
+
+2004-04-28  Raja R Harinath  <rharinath@novell.com>
+
+       * flowanalysis.cs (FlowBranchingException.LookupLabel): Add a null
+       check on current_vector.Block.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (BaseAccess.CommonResolve): Don't allow `base' in
+       a field initializer.  Fixes #56459.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (PropertyExpr.DoResolve/DoResolveLValue): Check whether
+       we're not attempting to use an indexer.  Fixes #52154.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Return): Don't create a return label if we don't
+       need it; reverts my change from January 20th.  Thanks to Ben
+       Maurer for this.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       According to the spec, `goto' can only leave a nested scope, but
+       never enter it.
+
+       * statement.cs (Block.LookupLabel): Only lookup in the current
+       block, don't recurse into parent or child blocks.
+       (Block.AddLabel): Check in parent and child blocks, report
+       CS0140/CS0158 if we find a duplicate.
+       (Block): Removed this indexer for label lookups.
+       (Goto.Resolve): Call LookupLabel() on our current FlowBranching;
+       this already does the error reporting for us.
+
+       * flowanalysis.cs
+       (FlowBranching.UsageVector.Block): New public variable; may be null.
+       (FlowBranching.CreateSibling): Added `Block' argument.
+       (FlowBranching.LookupLabel): New public virtual method.  Lookup a
+       label for the target of a `goto' and check whether we're not
+       leaving a `finally'.
+
 2004-04-27  Martin Baulig  <martin@ximian.com>
 
        * flowanalysis.cs (FlowBranching.UsageVector.MergeChild): If we're
        for a named field or property, implicity convert it to the correct
        type.
 
+>>>>>>> 1.1450
 2004-04-27  Raja R Harinath  <rharinath@novell.com>
 
        * statement.cs (Block.Block): Implicit blocks share
index a87f83621c78de07fb3440e5347e0923dc32edd4..8ffdfb7503002850322c73e74cf5581dfbd94ffe 100755 (executable)
@@ -967,6 +967,19 @@ namespace Mono.CSharp {
                                                ((BoolConstant) right).Value);
                                
                                }
+                               if (left is NullLiteral){
+                                       if (right is NullLiteral)
+                                               return new BoolConstant (true);
+                                       else if (right is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) right).Value == null);
+                               } else if (right is NullLiteral){
+                                       if (left is NullLiteral)
+                                               return new BoolConstant (true);
+                                       else if (left is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) left).Value == null);
+                               }
                                if (left is StringConstant && right is StringConstant){
                                        return new BoolConstant (
                                                ((StringConstant) left).Value ==
@@ -1008,6 +1021,19 @@ namespace Mono.CSharp {
                                                ((BoolConstant) left).Value !=
                                                ((BoolConstant) right).Value);
                                }
+                               if (left is NullLiteral){
+                                       if (right is NullLiteral)
+                                               return new BoolConstant (false);
+                                       else if (right is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) right).Value != null);
+                               } else if (right is NullLiteral){
+                                       if (left is NullLiteral)
+                                               return new BoolConstant (false);
+                                       else if (left is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) left).Value != null);
+                               }
                                if (left is StringConstant && right is StringConstant){
                                        return new BoolConstant (
                                                ((StringConstant) left).Value !=
index 1caa0d04dd582082c69e692f15840dbc97da79f6..ec3a079c06c00183272a02fa513eaae2e7ad3be6 100755 (executable)
@@ -28,6 +28,7 @@ namespace Mono.CSharp {
                public Expression Expr;
                EmitContext const_ec;
 
+               bool resolved = false;
                object ConstantValue = null;
                Type type;
 
@@ -178,16 +179,19 @@ namespace Mono.CSharp {
                ///  Looks up the value of a constant field. Defines it if it hasn't
                ///  already been. Similar to LookupEnumValue in spirit.
                /// </summary>
-               public object LookupConstantValue ()
+               public bool LookupConstantValue (out object value)
                {
-                       if (ConstantValue != null)
-                               return ConstantValue;
+                       if (resolved) {
+                               value = ConstantValue;
+                               return true;
+                       }
 
                        if (in_transit) {
                                Report.Error (110, Location,
                                              "The evaluation of the constant value for `" +
                                              Name + "' involves a circular definition.");
-                               return null;
+                               value = null;
+                               return false;
                        }
 
                        in_transit = true;
@@ -196,8 +200,10 @@ namespace Mono.CSharp {
                        //
                        // We might have cleared Expr ourselves in a recursive definition
                        //
-                       if (Expr == null)
-                               return null;
+                       if (Expr == null){
+                               value = null;
+                               return false;
+                       }
                        
                        Expr = Expr.Resolve (const_ec);
 
@@ -206,7 +212,8 @@ namespace Mono.CSharp {
                        if (Expr == null) {
                                if (errors == Report.Errors)
                                        Report.Error (150, Location, "A constant value is expected");
-                               return null;
+                               value = null;
+                               return false;
                        }
 
                        Constant ce = Expr as Constant;
@@ -224,19 +231,23 @@ namespace Mono.CSharp {
                                        Expr = ac.TurnIntoConstant ();
                                        if (Expr == null){
                                                Report.Error (150, Location, "A constant value is expected");
-                                               return null;
+                                               value = null;
+                                               return false;
                                        }
                                } else {
                                        if (errors == Report.Errors)
                                                Report.Error (150, Location, "A constant value is expected");
-                                       return null;
+                                       value = null;
+                                       return false;
                                }
                        }
 
                        if (type != ce.Type) {
                                ce = ChangeType (Location, ce, type);
-                               if (ce == null)
-                                       return null;
+                               if (ce == null){
+                                       value = null;
+                                       return false;
+                               }
                                Expr = ce;
                        }
                        ConstantValue = ce.GetValue ();
@@ -259,9 +270,11 @@ namespace Mono.CSharp {
                        FieldBuilder.SetConstant (ConstantValue);
 
                        if (!TypeManager.RegisterFieldValue (FieldBuilder, ConstantValue))
-                               return null;
+                               throw new Exception ("Cannot register const value");
 
-                       return ConstantValue;
+                       value = ConstantValue;
+                       resolved = true;
+                       return true;
                }
                
                
@@ -270,7 +283,8 @@ namespace Mono.CSharp {
                /// </summary>
                public override void Emit (TypeContainer parent)
                {
-                       LookupConstantValue ();
+                       object value;
+                       LookupConstantValue (out value);
                        base.Emit (parent);
                }
        }
index dda8f089102ab7be01014b040bcf685f7ff206df..bb73f8e4b06093f48e9510152148261c5e8c57d0 100755 (executable)
@@ -1013,7 +1013,10 @@ namespace Mono.CSharp {
                
                public override void Emit (EmitContext ec)
                {
-                       ec.ig.Emit (OpCodes.Ldstr, Value);
+                       if (Value == null)
+                               ec.ig.Emit (OpCodes.Ldnull);
+                       else
+                               ec.ig.Emit (OpCodes.Ldstr, Value);
                }
        }
 
index a89cf8f3106b49d2d6e42eed9558b73593b37ad5..5f14919d9eeb980458ead5e291594fb6bdc5a32b 100755 (executable)
@@ -329,7 +329,7 @@ namespace Mono.CSharp
                        }
                }
 
-                       static Assembly LoadAssemblyFromGac (string name)
+               static Assembly LoadAssemblyFromGac (string name)
                {
                        PropertyInfo gac = typeof (System.Environment).GetProperty ("GacPath",
                                        BindingFlags.Static|BindingFlags.NonPublic);
@@ -1456,7 +1456,8 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
-                               module_only.SetValue (CodeGen.Assembly.Builder, true, null);
+                               MethodInfo set_method = module_only.GetSetMethod (true);
+                               set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
                        }
 
                        TypeManager.AddModule (CodeGen.Module.Builder);
index 63c67dc18e87a68c1e833fbb0c5386fa05b7593a..da830b4129b7a17b818f61def007d3acfc0961b6 100755 (executable)
@@ -3227,6 +3227,16 @@ namespace Mono.CSharp {
                
                override public Expression DoResolve (EmitContext ec)
                {
+                       if (getter != null){
+                               if (TypeManager.GetArgumentTypes (getter).Length != 0){
+                                       Report.Error (
+                                               117, loc, "`{0}' does not contain a " +
+                                               "definition for `{1}'.", getter.DeclaringType,
+                                               Name);
+                                       return null;
+                               }
+                       }
+
                        if (getter == null){
                                //
                                // The following condition happens if the PropertyExpr was
@@ -3278,6 +3288,14 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       if (TypeManager.GetArgumentTypes (setter).Length != 1){
+                               Report.Error (
+                                       117, loc, "`{0}' does not contain a " +
+                                       "definition for `{1}'.", getter.DeclaringType,
+                                       Name);
+                               return null;
+                       }
+
                        if (!InstanceResolve (ec))
                                return null;
                        
index 4fd0e6887a8400cae16d1a361117be23ba0a8446..47b58f93e06031c35dc247695d651a959f6aa506 100755 (executable)
@@ -7137,10 +7137,10 @@ namespace Mono.CSharp {
                                        Const c = TypeManager.LookupConstant ((FieldBuilder) fi);
                                        
                                        if (c != null) {
-                                               object o = c.LookupConstantValue ();
-                                               if (o == null)
+                                               object o;
+                                               if (!c.LookupConstantValue (out o))
                                                        return null;
-                                               
+
                                                object real_value = ((Constant) c.Expr).GetValue ();
 
                                                return Constantify (real_value, fi.FieldType);
@@ -8475,6 +8475,11 @@ namespace Mono.CSharp {
                                Error (1511, "Keyword base is not allowed in static method");
                                return null;
                        }
+
+                       if (ec.IsFieldInitializer){
+                               Error (1512, "Keyword base is not available in the current context");
+                               return null;
+                       }
                        
                        member_lookup = MemberLookup (ec, ec.ContainerType, null, base_type,
                                                      member, AllMemberTypes, AllBindingFlags,
index a765bd4fe68e10cef0e3192244969fc9de322f51..120e958ab52c161b35fa360a3a405d4387a4b5c0 100644 (file)
@@ -434,6 +434,11 @@ namespace Mono.CSharp
                        // </summary>
                        public readonly Location Location;
 
+                       // <summary>
+                       //   This is only valid for SwitchSection, Try, Catch and Finally.
+                       // </summary>
+                       public readonly Block Block;
+
                        // <summary>
                        //   If this is true, then the usage vector has been modified and must be
                        //   merged when we're done with this branching.
@@ -474,9 +479,12 @@ namespace Mono.CSharp
                        //
                        // Normally, you should not use any of these constructors.
                        //
-                       public UsageVector (SiblingType type, UsageVector parent, Location loc, int num_params, int num_locals)
+                       public UsageVector (SiblingType type, UsageVector parent,
+                                           Block block, Location loc,
+                                           int num_params, int num_locals)
                        {
                                this.Type = type;
+                               this.Block = block;
                                this.Location = loc;
                                this.InheritsFrom = parent;
                                this.CountParameters = num_params;
@@ -503,15 +511,19 @@ namespace Mono.CSharp
                                id = ++next_id;
                        }
 
-                       public UsageVector (SiblingType type, UsageVector parent, Location loc)
-                               : this (type, parent, loc, parent.CountParameters, parent.CountLocals)
+                       public UsageVector (SiblingType type, UsageVector parent,
+                                           Block block, Location loc)
+                               : this (type, parent, block, loc,
+                                       parent.CountParameters, parent.CountLocals)
                        { }
 
                        public UsageVector (MyBitVector parameters, MyBitVector locals,
-                                           Reachability reachability, Location loc)
+                                           Reachability reachability, Block block,
+                                           Location loc)
                        {
                                this.Type = SiblingType.Block;
                                this.Location = loc;
+                               this.Block = block;
 
                                this.reachability = reachability;
                                this.parameters = parameters;
@@ -525,7 +537,9 @@ namespace Mono.CSharp
                        // </summary>
                        public UsageVector Clone ()
                        {
-                               UsageVector retval = new UsageVector (Type, null, Location, CountParameters, CountLocals);
+                               UsageVector retval = new UsageVector (
+                                       Type, null, Block, Location,
+                                       CountParameters, CountLocals);
 
                                if (retval.locals != null)
                                retval.locals = locals.Clone ();
@@ -938,13 +952,14 @@ namespace Mono.CSharp
                                local_map = Block.LocalMap;
 
                                UsageVector parent_vector = parent != null ? parent.CurrentUsageVector : null;
-                               vector = new UsageVector (stype, parent_vector, loc, param_map.Length, local_map.Length);
-                               
-
+                               vector = new UsageVector (
+                                       stype, parent_vector, Block, loc,
+                                       param_map.Length, local_map.Length);
                        } else {
                                param_map = Parent.param_map;
                                local_map = Parent.local_map;
-                               vector = new UsageVector (stype, Parent.CurrentUsageVector, loc);
+                               vector = new UsageVector (
+                                       stype, Parent.CurrentUsageVector, null, loc);
                        }
 
                        AddSibling (vector);
@@ -957,15 +972,33 @@ namespace Mono.CSharp
                // <summary>
                //   Creates a sibling of the current usage vector.
                // </summary>
-               public virtual void CreateSibling (SiblingType type)
+               public virtual void CreateSibling (Block block, SiblingType type)
                {
-                       AddSibling (new UsageVector (type, Parent.CurrentUsageVector, Location));
+                       UsageVector vector = new UsageVector (
+                               type, Parent.CurrentUsageVector, block, Location);
+                       AddSibling (vector);
 
                        Report.Debug (1, "  CREATED SIBLING", CurrentUsageVector);
                }
 
+               public void CreateSibling ()
+               {
+                       CreateSibling (null, SiblingType.Conditional);
+               }
+
                protected abstract void AddSibling (UsageVector uv);
 
+               public virtual LabeledStatement LookupLabel (string name, Location loc)
+               {
+                       if (Parent != null)
+                               return Parent.LookupLabel (name, loc);
+
+                       Report.Error (
+                               159, loc,
+                               "No such label `" + name + "' in this scope");
+                       return null;
+               }
+
                public abstract void Label (UsageVector origin_vectors);
 
                // <summary>
@@ -1075,7 +1108,8 @@ namespace Mono.CSharp
                        Report.Debug (2, "  MERGING SIBLINGS DONE", parameters, locals,
                                      reachability, Infinite);
 
-                       return new UsageVector (parameters, locals, reachability, Location);
+                       return new UsageVector (
+                               parameters, locals, reachability, null, Location);
                }
 
                protected abstract UsageVector Merge ();
@@ -1097,7 +1131,8 @@ namespace Mono.CSharp
                                throw new NotSupportedException ();
 
                        UsageVector vector = new UsageVector (
-                               SiblingType.Conditional, null, Location, param_map.Length, local_map.Length);
+                               SiblingType.Conditional, null, Block, Location,
+                               param_map.Length, local_map.Length);
 
                        UsageVector result = vector.MergeChild (this);
 
@@ -1269,6 +1304,18 @@ namespace Mono.CSharp
                        sibling_list = sibling;
                }
 
+               public override LabeledStatement LookupLabel (string name, Location loc)
+               {
+                       if (Block == null)
+                               return base.LookupLabel (name, loc);
+
+                       LabeledStatement s = Block.LookupLabel (name);
+                       if (s != null)
+                               return s;
+
+                       return base.LookupLabel (name, loc);
+               }
+
                public override void Label (UsageVector origin_vectors)
                {
                        if (!CurrentUsageVector.Reachability.IsUnreachable) {
@@ -1374,6 +1421,25 @@ namespace Mono.CSharp
                        finally_origins = vector;
                }
 
+               public override LabeledStatement LookupLabel (string name, Location loc)
+               {
+                       if (current_vector.Block == null)
+                               return base.LookupLabel (name, loc);
+
+                       LabeledStatement s = current_vector.Block.LookupLabel (name);
+                       if (s != null)
+                               return s;
+
+                       if (finally_vector != null) {
+                               Report.Error (
+                                       157, loc, "Control can not leave the body " +
+                                       "of the finally block");
+                               return null;
+                       }
+
+                       return base.LookupLabel (name, loc);
+               }
+
                public override void Label (UsageVector origin_vectors)
                {
                        CurrentUsageVector.MergeJumpOrigins (origin_vectors);
index 48fc22d1058879e3d5f2cddc3ea9484ca4c4d1b8..8641dc22b0fce5c96a7d6bc5c6a56731ddee2aae 100755 (executable)
@@ -670,6 +670,15 @@ namespace Mono.CSharp {
                                        else
                                                Report1530 (en.Location);
                        }
+
+                       //
+                       // Check for cycles in the struct layout
+                       //
+                       if (type_container_resolve_order != null){
+                               Hashtable seen = new Hashtable ();
+                               foreach (TypeContainer tc in type_container_resolve_order)
+                                       TypeManager.CheckStructCycles (tc, seen);
+                       }
                }
 
                //
index 21996b7320d15f419cae11d88861861d4cec8f4c..baf26f293d27e66cc78b112cf88647732269fbd5 100755 (executable)
@@ -171,7 +171,7 @@ namespace Mono.CSharp {
 
                        is_true_ret = ec.CurrentBranching.CurrentUsageVector.Reachability.IsUnreachable;
 
-                       ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Conditional);
+                       ec.CurrentBranching.CreateSibling ();
 
                        if ((FalseStatement != null) && !FalseStatement.Resolve (ec))
                                ok = false;
@@ -440,7 +440,7 @@ namespace Mono.CSharp {
 
                        ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
                        if (!infinite)
-                               ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Conditional);
+                               ec.CurrentBranching.CreateSibling ();
 
                        if (!Statement.Resolve (ec))
                                ok = false;
@@ -598,22 +598,15 @@ namespace Mono.CSharp {
                        if (Expr != null) {
                                Expr.Emit (ec);
 
-                               if (in_exc || !ec.IsLastStatement)
+                               if (in_exc)
                                        ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
                        }
 
                        if (in_exc) {
                                ec.NeedReturnLabel ();
                                ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
-                       } else if (ec.IsLastStatement) {
-                               // If we are the last statement in a top-level block, simply
-                               // emit a `ret'.
-                               ec.ig.Emit (OpCodes.Ret);
                        } else {
-                               // Otherwise, we always create a return label and jump to
-                               // it.
-                               ec.NeedReturnLabel ();
-                               ec.ig.Emit (OpCodes.Br, ec.ReturnLabel);
+                               ec.ig.Emit (OpCodes.Ret);
                        }
                }
        }
@@ -625,13 +618,9 @@ namespace Mono.CSharp {
                
                public override bool Resolve (EmitContext ec)
                {
-                       label = block.LookupLabel (target);
-                       if (label == null){
-                               Report.Error (
-                                       159, loc,
-                                       "No such label `" + target + "' in this scope");
+                       label = ec.CurrentBranching.LookupLabel (target, loc);
+                       if (label == null)
                                return false;
-                       }
 
                        // If this is a forward goto.
                        if (!label.IsDefined)
@@ -1235,19 +1224,22 @@ namespace Mono.CSharp {
                                return switch_block.AddLabel (name, target, loc);
 
                        Block cur = this;
-                       while (cur != null && cur.Implicit) {
-                               if (cur.LookupLabel (name) != null) {
+                       while (cur != null) {
+                               if (cur.DoLookupLabel (name) != null) {
                                        Report.Error (
                                                140, loc, "The label '{0}' is a duplicate",
                                                name);
                                        return false;
                                }
 
+                               if (!Implicit)
+                                       break;
+
                                cur = cur.Parent;
                        }
 
                        while (cur != null) {
-                               if (cur.LookupLabel (name) != null) {
+                               if (cur.DoLookupLabel (name) != null) {
                                        Report.Error (
                                                158, loc,
                                                "The label '{0}' shadows another label " +
@@ -1256,6 +1248,23 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
+                               if (children != null) {
+                                       foreach (Block b in children) {
+                                               LabeledStatement s = b.DoLookupLabel (name);
+                                               if (s == null)
+                                                       continue;
+
+                                               Report.Error (
+                                                       158, s.Location,
+                                                       "The label '{0}' shadows another " +
+                                                       "label by the same name in a " +
+                                                       "containing scope.",
+                                                       name);
+                                               return false;
+                                       }
+                               }
+
+
                                cur = cur.Parent;
                        }
 
@@ -1268,40 +1277,34 @@ namespace Mono.CSharp {
 
                public LabeledStatement LookupLabel (string name)
                {
-                       Hashtable l = new Hashtable ();
-                       
-                       return LookupLabel (name, l);
+                       LabeledStatement s = DoLookupLabel (name);
+                       if (s != null)
+                               return s;
+
+                       if (children == null)
+                               return null;
+
+                       foreach (Block child in children) {
+                               if (!child.Implicit)
+                                       continue;
+
+                               s = child.LookupLabel (name);
+                               if (s != null)
+                                       return s;
+                       }
+
+                       return null;
                }
 
-               //
-               // Lookups a label in the current block, parents and children.
-               // It skips during child recurssion on `source'
-               //
-               LabeledStatement LookupLabel (string name, Hashtable seen)
+               LabeledStatement DoLookupLabel (string name)
                {
                        if (switch_block != null)
-                               return switch_block.LookupLabel (name, seen);
+                               return switch_block.LookupLabel (name);
 
-                       if (seen [this] != null)
-                               return null;
-
-                       seen [this] = this;
-                       
                        if (labels != null)
                                if (labels.Contains (name))
                                        return ((LabeledStatement) labels [name]);
 
-                       if (children != null){
-                               foreach (Block b in children){
-                                       LabeledStatement s = b.LookupLabel (name, seen);
-                                       if (s != null)
-                                               return s;
-                               }
-                       }
-
-                       if (Parent != null)
-                               return Parent.LookupLabel (name, seen);
-
                        return null;
                }
 
@@ -1496,15 +1499,6 @@ namespace Mono.CSharp {
                        return e != null;
                }
                
-               /// <summary>
-               ///   Use to fetch the statement associated with this label
-               /// </summary>
-               public Statement this [string name] {
-                       get {
-                               return (Statement) labels [name];
-                       }
-               }
-
                Parameters parameters = null;
                public Parameters Parameters {
                        get {
@@ -2617,7 +2611,8 @@ namespace Mono.CSharp {
                        bool first = true;
                        foreach (SwitchSection ss in Sections){
                                if (!first)
-                                       ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.SwitchSection);
+                                       ec.CurrentBranching.CreateSibling (
+                                               null, FlowBranching.SiblingType.SwitchSection);
                                else
                                        first = false;
 
@@ -2627,7 +2622,8 @@ namespace Mono.CSharp {
 
 
                        if (!got_default)
-                               ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.SwitchSection);
+                               ec.CurrentBranching.CreateSibling (
+                                       null, FlowBranching.SiblingType.SwitchSection);
 
                        FlowBranching.Reachability reachability = ec.EndFlowBranching ();
                        ec.Switch = old_switch;
@@ -3191,7 +3187,9 @@ namespace Mono.CSharp {
                        Report.Debug (1, "START OF CATCH BLOCKS", vector);
 
                        foreach (Catch c in Specific){
-                               ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Catch);
+                               ec.CurrentBranching.CreateSibling (
+                                       c.Block, FlowBranching.SiblingType.Catch);
+
                                Report.Debug (1, "STARTED SIBLING FOR CATCH", ec.CurrentBranching);
 
                                if (c.Name != null) {
@@ -3209,7 +3207,9 @@ namespace Mono.CSharp {
                        Report.Debug (1, "END OF CATCH BLOCKS", ec.CurrentBranching);
 
                        if (General != null){
-                               ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Catch);
+                               ec.CurrentBranching.CreateSibling (
+                                       General.Block, FlowBranching.SiblingType.Catch);
+
                                Report.Debug (1, "STARTED SIBLING FOR GENERAL", ec.CurrentBranching);
 
                                if (!General.Resolve (ec))
@@ -3220,7 +3220,9 @@ namespace Mono.CSharp {
 
                        if (Fini != null) {
                                if (ok)
-                                       ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Finally);
+                                       ec.CurrentBranching.CreateSibling (
+                                               Fini, FlowBranching.SiblingType.Finally);
+
                                Report.Debug (1, "STARTED SIBLING FOR FINALLY", ec.CurrentBranching, vector);
 
                                if (!Fini.Resolve (ec))
@@ -3585,7 +3587,7 @@ namespace Mono.CSharp {
                        bool ok = true;
 
                        ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
-                       ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Conditional);
+                       ec.CurrentBranching.CreateSibling ();
 
                        //
                        //
index aab48f18c77c932e6899b02da04aee334baf9d29..f60d27d97803d9d1303d67bc11605a318e221f1a 100755 (executable)
@@ -1521,6 +1521,11 @@ public class TypeManager {
                        return false;
        }
 
+       public static bool IsBuiltinType (TypeContainer tc)
+       {
+               return IsBuiltinType (tc.TypeBuilder);
+       }
+
        //
        // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
        // the pieces in the code where we use IsBuiltinType and special case decimal_type.
@@ -2153,6 +2158,57 @@ public class TypeManager {
                return true;
        }
 
+       public static bool CheckStructCycles (TypeContainer tc, Hashtable seen)
+       {
+               Hashtable hash = new Hashtable ();
+               return CheckStructCycles (tc, seen, hash);
+       }
+
+       public static bool CheckStructCycles (TypeContainer tc, Hashtable seen,
+                                             Hashtable hash)
+       {
+               if (!(tc is Struct) || IsBuiltinType (tc))
+                       return true;
+
+               //
+               // `seen' contains all types we've already visited.
+               //
+               if (seen.Contains (tc))
+                       return true;
+               seen.Add (tc, null);
+
+               //
+               // `hash' contains all types in the current path.
+               //
+               hash.Add (tc, null);
+
+               if (tc.Fields == null)
+                       return true;
+
+               foreach (Field field in tc.Fields) {
+                       if (field.FieldBuilder.IsStatic)
+                               continue;
+
+                       Type ftype = field.FieldBuilder.FieldType;
+                       TypeContainer ftc = LookupTypeContainer (ftype);
+                       if (ftc == null)
+                               continue;
+
+                       if (hash.Contains (ftc)) {
+                               Report.Error (523, tc.Location,
+                                             "Struct member `{0}.{1}' of type `{2}' " +
+                                             "causes a cycle in the struct layout",
+                                             tc.Name, field.Name, ftc.Name);
+                               return false;
+                       }
+
+                       if (!CheckStructCycles (ftc, seen, hash))
+                               return false;
+               }
+
+               return true;
+       }
+
        /// <summary>
        ///   Given an array of interface types, expand and eliminate repeated ocurrences
        ///   of an interface.