2005-01-27 Marek Safar <marek.safar@seznam.cz>
authorMarek Safar <marek.safar@gmail.com>
Thu, 27 Jan 2005 08:36:01 +0000 (08:36 -0000)
committerMarek Safar <marek.safar@gmail.com>
Thu, 27 Jan 2005 08:36:01 +0000 (08:36 -0000)
* expression.cs (Indirection): Implemented IVariable interface
to support indirection in AddressOf operator.
(PointerArithmetic.Emit): Add optimalization for case where
result can be precomputed.

svn path=/trunk/mcs/; revision=39626

mcs/mcs/ChangeLog
mcs/mcs/expression.cs

index 9f13da3d53dd65068611c197d7b39171e92c63f6..df5a98a179c867a29ea2b86eb00182e0f29aaf40 100644 (file)
@@ -1,3 +1,10 @@
+2005-01-27  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (Indirection): Implemented IVariable interface
+       to support indirection in AddressOf operator.
+       (PointerArithmetic.Emit): Add optimalization for case where
+       result can be precomputed.
+
 2005-01-26  Martin Baulig  <martin@ximian.com>
 
        * class.cs (TypeContainer.AttributeTargets): Return the correct
index aeafb162a48e719251175054f81c03476450a571..95dbf5f2003be97d34d789912f90f9ea6cd40ea1 100644 (file)
@@ -431,13 +431,15 @@ namespace Mono.CSharp {
                                }
 
                                IVariable variable = Expr as IVariable;
-                               if (!ec.InFixedInitializer && ((variable == null) || !variable.VerifyFixed (false))) {
+                               bool is_fixed = variable != null && variable.VerifyFixed (false);
+
+                               if (!ec.InFixedInitializer && !is_fixed) {
                                        Error (212, "You can only take the address of an unfixed expression inside " +
                                               "of a fixed statement initializer");
                                        return null;
                                }
 
-                               if (ec.InFixedInitializer && ((variable != null) && variable.VerifyFixed (false))) {
+                               if (ec.InFixedInitializer && is_fixed) {
                                        Error (213, "You can not fix an already fixed expression");
                                        return null;
                                }
@@ -659,7 +661,7 @@ namespace Mono.CSharp {
        // after semantic analysis (this is so we can take the address
        // of an indirection).
        //
-       public class Indirection : Expression, IMemoryLocation, IAssignMethod {
+       public class Indirection : Expression, IMemoryLocation, IAssignMethod, IVariable {
                Expression expr;
                LocalTemporary temporary;
                bool prepared;
@@ -733,6 +735,21 @@ namespace Mono.CSharp {
                {
                        return "*(" + expr + ")";
                }
+
+               #region IVariable Members
+
+               public VariableInfo VariableInfo {
+                       get {
+                               return null;
+                       }
+               }
+
+               public bool VerifyFixed (bool is_expression)
+               {
+                       return true;
+               }
+
+               #endregion
        }
        
        /// <summary>
@@ -3413,17 +3430,26 @@ namespace Mono.CSharp {
                                //
                                left.Emit (ec);
                                ig.Emit (OpCodes.Conv_I);
-                               right.Emit (ec);
-                               if (size != 1){
-                                       if (size == 0)
-                                               ig.Emit (OpCodes.Sizeof, element);
-                                       else 
-                                               IntLiteral.EmitInt (ig, size);
-                                       if (rtype == TypeManager.int64_type)
-                                               ig.Emit (OpCodes.Conv_I8);
-                                       else if (rtype == TypeManager.uint64_type)
-                                               ig.Emit (OpCodes.Conv_U8);
-                                       ig.Emit (OpCodes.Mul);
+
+                               Constant right_const = right as Constant;
+                               if (right_const != null && size != 0) {
+                                       Expression ex = ConstantFold.BinaryFold (ec, Binary.Operator.Multiply, new IntConstant (size), right_const, loc);
+                                       if (ex == null)
+                                               return;
+                                       ex.Emit (ec);
+                               } else {
+                                       right.Emit (ec);
+                                       if (size != 1){
+                                               if (size == 0)
+                                                       ig.Emit (OpCodes.Sizeof, element);
+                                               else 
+                                                       IntLiteral.EmitInt (ig, size);
+                                               if (rtype == TypeManager.int64_type)
+                                                       ig.Emit (OpCodes.Conv_I8);
+                                               else if (rtype == TypeManager.uint64_type)
+                                                       ig.Emit (OpCodes.Conv_U8);
+                                               ig.Emit (OpCodes.Mul);
+                                       }
                                }
                                
                                if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)