r72953 - in trunk/mcs: gmcs mcs tests

2 views
Skip to first unread message

Miguel de Icaza (miguel@novell.com)

unread,
Feb 15, 2007, 2:45:29 PM2/15/07
to mono-p...@lists.ximian.com, ximian....@gmail.com, mono-svn-patche...@googlegroups.com
Author: miguel
Date: 2007-02-15 14:45:26 -0500 (Thu, 15 Feb 2007)
New Revision: 72953

Added:
trunk/mcs/tests/ltest-2.cs
Modified:
trunk/mcs/gmcs/ChangeLog
trunk/mcs/gmcs/cs-parser.jay
trunk/mcs/gmcs/generic.cs
trunk/mcs/mcs/ChangeLog
trunk/mcs/mcs/anonymous.cs
trunk/mcs/mcs/assign.cs
trunk/mcs/mcs/codegen.cs
trunk/mcs/mcs/constant.cs
trunk/mcs/mcs/delegate.cs
trunk/mcs/mcs/ecore.cs
trunk/mcs/mcs/expression.cs
trunk/mcs/mcs/generic.cs
trunk/mcs/mcs/lambda.cs
trunk/mcs/mcs/lambda.todo
trunk/mcs/mcs/report.cs
trunk/mcs/mcs/statement.cs
Log:
2007-02-15 Miguel de Icaza <mig...@novell.com>

* report.cs (DisableErrors, EnableErrors): used to prevent error
output when we are "trying" to compile various methods with
different types.

* ecore.cs (Expression): Add Clone method that calls the virtual
CloneTo method. The current CloneTo method in Expression throws
an exception so we can track down all the places where this must
be implemented (not using abstract, because that would be a lot of
up-front-work before we can start testing the implementation
idea).

Important: we only need Clone capabilities for expressions created
by the parser, as the expressions we will be cloning are
expressions in the pre-resolved state. This vastly simplifies
the work required.

(SimpleName): Add CloneTo that does nothing.
(EmptyCast): Add CloneTo.

* expression.cs (Binary): Implement CloneTo.
(Invocation.IsApplicable): Store the current ec in
EmitContext.TempEc and restore it on return. This is used so we
do not have to sprinkle hundres of methods with an extra
EmitContext, we know that the only user is the lambda expression
ImplicitConversionExists code.

(Argument): Add Cloning capabilities.
(LocalVariableReference, ParenthesizedExpression, Unary, Probe,
Cast, Conditional, ArrayCreation, InvocationOrCast, Invocation,
ArglistAccess, ArgList, TypeOf, SizeOf, CheckedExpr,
UnCheckedExpr, ElementAccess, BaseAccess, BaseIndexerAccess,
IndexerAccess): Add Clone capability.

(LocalVariableReference, This): TODO: needs cloned Block mapping.

(Argument): Add cloning capability.

* assign.cs (Assign): Implement CloneTo.

* anonymous.cs (ImplicitStandardConversionExists): Make virtual.

* lambda.cs (ImplicitStandardConversionExists): Implement lambda
version by calling Convert with the EmitContext (that we are
currently storing in ec, this is not great, but will do for now,
to avoid passing EmitContext parameters to hundreds of functions
that do not need them now).

(SetExpression): Remove, it is not needed.

(ContextualReturn): Implement CloneTo.

* statement.cs (Statement): Implement cloning infrastructure,
similar to expressions.

(Block): Partial implementation of Clone for statements.

(Return): Implement clone.

* constant.cs (Constant.CloneTo): New method, does nothing.

* codegen.cs (TempEc): Add a static EmitContext as a temporary
solution, until we decide how to exactly do this.

2007-02-15 Miguel de Icaza <mig...@novell.com>

* Remove the call to SetExpression for lambda expressions, we do
not actually need it.

Remove expression tracking code as its not needed.

Modified: trunk/mcs/gmcs/ChangeLog
===================================================================
--- trunk/mcs/gmcs/ChangeLog 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/gmcs/ChangeLog 2007-02-15 19:45:26 UTC (rev 72953)
@@ -1,3 +1,10 @@
+2007-02-15 Miguel de Icaza <mig...@novell.com>
+
+ * Remove the call to SetExpression for lambda expressions, we do
+ not actually need it.
+
+ Remove expression tracking code as its not needed.
+
2007-02-11 Miguel de Icaza <mig...@novell.com>

* cs-parser.jay (lambda_expression_body): when the body is an

Modified: trunk/mcs/gmcs/cs-parser.jay
===================================================================
--- trunk/mcs/gmcs/cs-parser.jay 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/gmcs/cs-parser.jay 2007-02-15 19:45:26 UTC (rev 72953)
@@ -3449,7 +3449,7 @@
}
block
{
- $$ = end_anonymous ((ToplevelBlock) $4, null, (Location) $1);
+ $$ = end_anonymous ((ToplevelBlock) $4, (Location) $1);
}
;

@@ -3909,13 +3909,11 @@
expression
{
Block b = end_block (lexer.Location);
- oob_stack.Push ($2);
b.AddStatement (new ContextualReturn ((Expression) $2));
$$ = b;
}
| block {
$$ = $1;
- oob_stack.Push (null);
}
;

@@ -3932,7 +3930,7 @@
}
lambda_expression_body
{
- $$ = end_anonymous ((ToplevelBlock) $4, (Expression) oob_stack.Pop (), (Location) $2);
+ $$ = end_anonymous ((ToplevelBlock) $4, (Location) $2);
}
| OPEN_PARENS_LAMBDA opt_lambda_parameter_list CLOSE_PARENS ARROW
{
@@ -3940,7 +3938,7 @@
}
lambda_expression_body
{
- $$ = end_anonymous ((ToplevelBlock) $6, (Expression) oob_stack.Pop (), (Location) $4);
+ $$ = end_anonymous ((ToplevelBlock) $6, (Location) $4);
}
;

@@ -5542,7 +5540,7 @@
* means that we have a Statement instead of an Expression embedded
*/
AnonymousMethodExpression
-end_anonymous (ToplevelBlock anon_block, Expression lambda_expr, Location loc)
+end_anonymous (ToplevelBlock anon_block, Location loc)
{
AnonymousMethodExpression retval;

@@ -5555,9 +5553,6 @@
} else {
anon_block.Parent = current_block;

- if (lambda_expr != null)
- ((LambdaExpression) current_anonymous_method).SetExpression (lambda_expr);
-
current_anonymous_method.Block = anon_block;
if ((anonymous_host != null) && (current_anonymous_method.Parent == null))
anonymous_host.AddAnonymousMethod (current_anonymous_method);

Modified: trunk/mcs/gmcs/generic.cs
===================================================================
--- trunk/mcs/gmcs/generic.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/gmcs/generic.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -1271,6 +1271,15 @@
}
return ok;
}
+
+ public TypeArguments Clone ()
+ {
+ TypeArguments copy = new TypeArguments (Location);
+ foreach (Expression ta in args)
+ copy.args.Add (ta);
+
+ return copy;
+ }
}

public class TypeParameterName : SimpleName

Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/ChangeLog 2007-02-15 19:45:26 UTC (rev 72953)
@@ -1,3 +1,68 @@
+2007-02-15 Miguel de Icaza <mig...@novell.com>
+
+ * report.cs (DisableErrors, EnableErrors): used to prevent error
+ output when we are "trying" to compile various methods with
+ different types.
+
+ * ecore.cs (Expression): Add Clone method that calls the virtual
+ CloneTo method. The current CloneTo method in Expression throws
+ an exception so we can track down all the places where this must
+ be implemented (not using abstract, because that would be a lot of
+ up-front-work before we can start testing the implementation
+ idea).
+
+ Important: we only need Clone capabilities for expressions created
+ by the parser, as the expressions we will be cloning are
+ expressions in the pre-resolved state. This vastly simplifies
+ the work required.
+
+ (SimpleName): Add CloneTo that does nothing.
+ (EmptyCast): Add CloneTo.
+
+ * expression.cs (Binary): Implement CloneTo.
+ (Invocation.IsApplicable): Store the current ec in
+ EmitContext.TempEc and restore it on return. This is used so we
+ do not have to sprinkle hundres of methods with an extra
+ EmitContext, we know that the only user is the lambda expression
+ ImplicitConversionExists code.
+
+ (Argument): Add Cloning capabilities.
+ (LocalVariableReference, ParenthesizedExpression, Unary, Probe,
+ Cast, Conditional, ArrayCreation, InvocationOrCast, Invocation,
+ ArglistAccess, ArgList, TypeOf, SizeOf, CheckedExpr,
+ UnCheckedExpr, ElementAccess, BaseAccess, BaseIndexerAccess,
+ IndexerAccess): Add Clone capability.
+
+ (LocalVariableReference, This): TODO: needs cloned Block mapping.
+
+ (Argument): Add cloning capability.
+
+ * assign.cs (Assign): Implement CloneTo.
+
+ * anonymous.cs (ImplicitStandardConversionExists): Make virtual.
+
+ * lambda.cs (ImplicitStandardConversionExists): Implement lambda
+ version by calling Convert with the EmitContext (that we are
+ currently storing in ec, this is not great, but will do for now,
+ to avoid passing EmitContext parameters to hundreds of functions
+ that do not need them now).
+
+ (SetExpression): Remove, it is not needed.
+
+ (ContextualReturn): Implement CloneTo.
+
+ * statement.cs (Statement): Implement cloning infrastructure,
+ similar to expressions.
+
+ (Block): Partial implementation of Clone for statements.
+
+ (Return): Implement clone.
+
+ * constant.cs (Constant.CloneTo): New method, does nothing.
+
+ * codegen.cs (TempEc): Add a static EmitContext as a temporary
+ solution, until we decide how to exactly do this.
+
2007-02-14 Marek Safar <marek...@gmail.com>

A fix for bug #80493
@@ -27,6 +92,11 @@

2007-02-13 Marek Safar <marek...@gmail.com>

+ Another fix for bug #80749
+ * pending.cs: Abstract class has priority over interfaces.
+
+2007-02-13 Marek Safar <marek...@gmail.com>
+
* class.cs Better error message.

* driver.cs: Add shorter versions of -optimize option.

Modified: trunk/mcs/mcs/anonymous.cs
===================================================================
--- trunk/mcs/mcs/anonymous.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/anonymous.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -1149,7 +1149,7 @@
TypeManager.CSharpName (t));
}

- public bool ImplicitStandardConversionExists (Type delegate_type)
+ public virtual bool ImplicitStandardConversionExists (Type delegate_type)
{
if (Parameters == null)
return true;
@@ -1332,6 +1332,15 @@
public bool IsIterator {
get { return false; }
}
+
+ protected override void CloneTo (Expression t)
+ {
+ AnonymousMethodExpression target = (AnonymousMethodExpression) t;
+
+ throw new Exception ("Must map the block");
+
+ target.Parameters = Parameters.Clone ();
+ }
}

public abstract class AnonymousContainer : IAnonymousContainer

Modified: trunk/mcs/mcs/assign.cs
===================================================================
--- trunk/mcs/mcs/assign.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/assign.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -582,6 +582,14 @@
{
Emit (ec, true);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ Assign _target = (Assign) t;
+
+ _target.target = target.Clone ();
+ _target.source = source.Clone ();
+ }
}


@@ -667,5 +675,12 @@
source = new Binary (op, target, original_source);
return base.DoResolve (ec);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ CompoundAssign target = (CompoundAssign) t;
+
+ target.original_source = original_source.Clone ();
+ }
}
}

Modified: trunk/mcs/mcs/codegen.cs
===================================================================
--- trunk/mcs/mcs/codegen.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/codegen.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -383,6 +383,8 @@
Emitting
}

+ public static EmitContext TempEc;
+
bool isAnonymousMethodAllowed = true;

Phase current_phase;

Modified: trunk/mcs/mcs/constant.cs
===================================================================
--- trunk/mcs/mcs/constant.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/constant.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -216,6 +216,11 @@
public virtual bool IsZeroInteger {
get { return false; }
}
+
+ protected override void CloneTo (Expression target)
+ {
+ // CloneTo: Nothing, we do not keep any state on this expression
+ }
}

public abstract class IntegralConstant : Constant {

Modified: trunk/mcs/mcs/delegate.cs
===================================================================
--- trunk/mcs/mcs/delegate.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/delegate.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -617,7 +617,6 @@
public override string DocCommentHeader {
get { return "T:"; }
}
-
}

//

Modified: trunk/mcs/mcs/ecore.cs
===================================================================
--- trunk/mcs/mcs/ecore.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/ecore.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -1148,7 +1148,39 @@

return target;
}
-
+
+ //
+ // Derived classes implement this method by cloning the fields that
+ // could become altered during the Resolve stage
+ //
+ // Only expressions that are created for the parser need to implement
+ // this.
+ //
+ protected virtual void CloneTo (Expression target)
+ {
+ throw new NotImplementedException (
+ String.Format (
+ "CloneTo not implemented for expression {0}", this.GetType ()));
+ }
+
+ //
+ // Clones an expression created by the parser.
+ //
+ // We only support expressions created by the parser so far, not
+ // expressions that have been resolved (many more classes would need
+ // to implement CloneTo).
+ //
+ // This infrastructure is here merely for Lambda expressions which
+ // compile the same code using different type values for the same
+ // arguments to find the correct overload
+ //
+ public Expression Clone ()
+ {
+ Expression cloned = (Expression) MemberwiseClone ();
+ CloneTo (cloned);
+
+ return cloned;
+ }
}

/// <summary>
@@ -1195,7 +1227,7 @@
///
/// </summary>
public class EmptyCast : Expression {
- protected readonly Expression child;
+ protected Expression child;

public EmptyCast (Expression child, Type return_type)
{
@@ -1223,6 +1255,12 @@
return child.GetAttributableValue (valueType, out value);
}

+ protected override void CloneTo (Expression t)
+ {
+ EmptyCast target = (EmptyCast) t;
+
+ target.child = child.Clone ();
+ }
}

/// <summary>
@@ -2344,6 +2382,11 @@
{
return Name;
}
+
+ protected override void CloneTo (Expression target)
+ {
+ // CloneTo: Nothing, we do not keep any state on this expression
+ }
}

/// <summary>

Modified: trunk/mcs/mcs/expression.cs
===================================================================
--- trunk/mcs/mcs/expression.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/expression.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -114,6 +114,13 @@
return Expr.Location;
}
}
+
+ protected override void CloneTo (Expression t)
+ {
+ ParenthesizedExpression target = (ParenthesizedExpression) t;
+
+ target.Expr = Expr.Clone ();
+ }
}

/// <summary>
@@ -659,7 +666,13 @@
{
return "Unary (" + Oper + ", " + Expr + ")";
}
-
+
+ protected override void CloneTo (Expression t)
+ {
+ Unary target = (Unary) t;
+
+ target.Expr = Expr.Clone ();
+ }
}

//
@@ -1025,6 +1038,13 @@
{
EmitCode (ec, false);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ UnaryMutator target = (UnaryMutator) t;
+
+ target.expr = expr.Clone ();
+ }
}

/// <summary>
@@ -1069,6 +1089,15 @@
}
return this;
}
+
+ protected override void CloneTo (Expression t)
+ {
+ Probe target = (Probe) t;
+
+ target.expr = expr.Clone ();
+ target.ProbeType = ProbeType.Clone ();
+ }
+
}

/// <summary>
@@ -1386,6 +1415,14 @@
{
throw new Exception ("Should not happen");
}
+
+ protected override void CloneTo (Expression t)
+ {
+ Cast target = (Cast) t;
+
+ target.target_type = target_type.Clone ();
+ target.expr = expr.Clone ();
+ }
}

/// <summary>
@@ -2783,6 +2820,14 @@

ig.Emit (opcode);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ Binary target = (Binary) t;
+
+ target.left = left.Clone ();
+ target.right = right.Clone ();
+ }
}

//
@@ -3334,6 +3379,14 @@
ig.MarkLabel (end_target);
}

+ protected override void CloneTo (Expression t)
+ {
+ Conditional target = (Conditional) t;
+
+ target.expr = expr.Clone ();
+ target.trueExpr = trueExpr.Clone ();
+ target.falseExpr = falseExpr.Clone ();
+ }
}

public abstract class VariableReference : Expression, IAssignMethod, IMemoryLocation {
@@ -3587,6 +3640,15 @@
{
return String.Format ("{0} ({1}:{2})", GetType (), Name, loc);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ //
+ // We need an infrastructure in CloneTo that can be used remap
+ // old block pointers to new block pointers
+ //
+ throw new Exception ("Do something about the block we point to");
+ }
}

/// <summary>
@@ -3909,13 +3971,18 @@
else
ml.AddressOf (ec, mode);
}
+
+ public Argument Clone ()
+ {
+ return new Argument (Expr.Clone (), ArgType);
+ }
}

/// <summary>
/// Invocation of methods or delegates.
/// </summary>
public class Invocation : ExpressionStatement {
- public readonly ArrayList Arguments;
+ public ArrayList Arguments;

Expression expr;
MethodBase method = null;
@@ -4450,12 +4517,18 @@

if (a_mod == p_mod) {
Type pt = pd.ParameterType (i);
+ EmitContext prevec = EmitContext.TempEc;
+ EmitContext.TempEc = ec;

- if (a_mod == Parameter.Modifier.NONE) {
- if (!TypeManager.IsEqual (a.Type, pt) &&
- !Convert.ImplicitConversionExists (ec, a.Expr, pt))
- return false;
- continue;
+ try {
+ if (a_mod == Parameter.Modifier.NONE) {
+ if (!TypeManager.IsEqual (a.Type, pt) &&
+ !Convert.ImplicitConversionExists (ec, a.Expr, pt))
+ return false;
+ continue;
+ }
+ } finally {
+ EmitContext.TempEc = prevec;
}

if (pt != a.Type)
@@ -5392,6 +5465,19 @@
ec.ig.Emit (OpCodes.Pop);
}
}
+
+ protected override void CloneTo (Expression t)
+ {
+ Invocation target = (Invocation) t;
+
+ if (Arguments != null){
+ target.Arguments = new ArrayList ();
+ foreach (Argument a in Arguments)
+ target.Arguments.Add (a.Clone ());
+ }
+
+ expr = expr.Clone ();
+ }
}

public class InvocationOrCast : ExpressionStatement
@@ -5491,6 +5577,14 @@
{
throw new Exception ("Cannot happen");
}
+
+ protected override void CloneTo (Expression t)
+ {
+ InvocationOrCast target = (InvocationOrCast) t;
+
+ target.expr = expr.Clone ();
+ target.argument = argument.Clone ();
+ }
}

//
@@ -5508,7 +5602,7 @@
/// Implements the new expression
/// </summary>
public class New : ExpressionStatement, IMemoryLocation {
- public readonly ArrayList Arguments;
+ public ArrayList Arguments;

//
// During bootstrap, it contains the RequestedType,
@@ -5881,6 +5975,19 @@

((IMemoryLocation) value_target).AddressOf (ec, Mode);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ New target = (New) t;
+
+ target.RequestedType = RequestedType.Clone ();
+ if (Arguments != null){
+ target.Arguments = new ArrayList ();
+ foreach (Argument a in Arguments){
+ target.Arguments.Add (a.Clone ());
+ }
+ }
+ }
}

/// <summary>
@@ -6591,6 +6698,22 @@
value = ret;
return true;
}
+
+ protected override void CloneTo (Expression t)
+ {
+ ArrayCreation target = (ArrayCreation) t;
+
+ target.requested_base_type = requested_base_type.Clone ();
+ target.arguments = new ArrayList ();
+ foreach (Argument a in arguments)
+ target.arguments.Add (a.Clone ());
+
+ if (initializers != null){
+ target.initializers = new ArrayList ();
+ foreach (Expression initializer in initializers)
+ target.initializers.Add (initializer.Clone ());
+ }
+ }
}

public sealed class CompilerGeneratedThis : This
@@ -6796,6 +6919,13 @@
ec.ig.Emit (OpCodes.Ldarg_0);
}
}
+
+ protected override void CloneTo (Expression t)
+ {
+ This target = (This) t;
+
+ throw new Exception ("Must do block remapping");
+ }
}

/// <summary>
@@ -6827,6 +6957,11 @@
{
ec.ig.Emit (OpCodes.Arglist);
}
+
+ protected override void CloneTo (Expression target)
+ {
+ // nothing.
+ }
}

/// <summary>
@@ -6834,7 +6969,7 @@
/// </summary>
public class Arglist : Expression
{
- public readonly Argument[] Arguments;
+ public Argument[] Arguments;

public Arglist (Argument[] args, Location l)
{
@@ -6869,6 +7004,15 @@
foreach (Argument arg in Arguments)
arg.Emit (ec);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ Arglist target = (Arglist) t;
+
+ target.Arguments = new Argument [Arguments.Length];
+ for (int i = 0; i < Arguments.Length; i++)
+ target.Arguments [i] = Arguments [i].Clone ();
+ }
}

//
@@ -6898,7 +7042,7 @@
/// Implements the typeof operator
/// </summary>
public class TypeOf : Expression {
- readonly Expression QueriedType;
+ Expression QueriedType;
protected Type typearg;

public TypeOf (Expression queried_type, Location l)
@@ -6963,6 +7107,13 @@
return typearg;
}
}
+
+ protected override void CloneTo (Expression t)
+ {
+ TypeOf target = (TypeOf) t;
+
+ target.QueriedType = QueriedType.Clone ();
+ }
}

/// <summary>
@@ -7048,6 +7199,13 @@
else
IntConstant.EmitInt (ec.ig, size);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ SizeOf target = (SizeOf) t;
+
+ target.QueriedType = QueriedType.Clone ();
+ }
}

/// <summary>
@@ -7131,6 +7289,11 @@
{
return ToString ();
}
+
+ protected override void CloneTo (Expression t)
+ {
+ // Nothing
+ }
}

/// <summary>
@@ -7408,6 +7571,13 @@
{
return expr.GetSignatureForError () + "." + Identifier;
}
+
+ protected override void CloneTo (Expression t)
+ {
+ MemberAccess target = (MemberAccess) t;
+
+ target.expr = expr.Clone ();
+ }
}

/// <summary>
@@ -7450,6 +7620,13 @@
using (ec.With (EmitContext.Flags.AllCheckStateFlags, true))
Expr.EmitBranchable (ec, target, onTrue);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ CheckedExpr target = (CheckedExpr) t;
+
+ target.Expr = Expr.Clone ();
+ }
}

/// <summary>
@@ -7492,6 +7669,13 @@
using (ec.With (EmitContext.Flags.AllCheckStateFlags, false))
Expr.EmitBranchable (ec, target, onTrue);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ UnCheckedExpr target = (UnCheckedExpr) t;
+
+ target.Expr = Expr.Clone ();
+ }
}

/// <summary>
@@ -7623,6 +7807,16 @@
{
throw new Exception ("Should never be reached");
}
+
+ protected override void CloneTo (Expression t)
+ {
+ ElementAccess target = (ElementAccess) t;
+
+ target.Expr = Expr.Clone ();
+ target.Arguments = new ArrayList ();
+ foreach (Argument a in Arguments)
+ target.Arguments.Add (a.Clone ());
+ }
}

/// <summary>
@@ -8357,6 +8551,19 @@
// FIXME: print the argument list of the indexer
return instance_expr.GetSignatureForError () + ".this[...]";
}
+
+ protected override void CloneTo (Expression t)
+ {
+ IndexerAccess target = (IndexerAccess) t;
+
+ if (arguments != null){
+ target.arguments = new ArrayList ();
+ foreach (Argument a in arguments)
+ target.arguments.Add (a.Clone ());
+ }
+ if (instance_expr != null)
+ target.instance_expr = instance_expr.Clone ();
+ }
}

/// <summary>
@@ -8364,6 +8571,7 @@
/// </summary>
public class BaseAccess : Expression {
public readonly string Identifier;
+ TypeArguments args;

public BaseAccess (string member, Location l)
{
@@ -8377,8 +8585,6 @@
this.args = args;
}

- TypeArguments args;
-
public override Expression DoResolve (EmitContext ec)
{
Expression c = CommonResolve (ec);
@@ -8470,6 +8676,13 @@
{
throw new Exception ("Should never be called");
}
+
+ protected override void CloneTo (Expression t)
+ {
+ BaseAccess target = (BaseAccess) t;
+
+ target.args = args.Clone ();
+ }
}

/// <summary>
@@ -8701,6 +8914,13 @@
{
return left.GetSignatureForError () + dim;
}
+
+ protected override void CloneTo (Expression t)
+ {
+ ComposedCast target = (ComposedCast) t;
+
+ target.left = left.Clone ();
+ }
}

public class FixedBufferPtr : Expression {
@@ -8853,5 +9073,12 @@
ig.Emit (OpCodes.Mul);
ig.Emit (OpCodes.Localloc);
}
+
+ protected override void CloneTo (Expression t)
+ {
+ StackAlloc target = (StackAlloc) t;
+ target.count = count.Clone ();
+ target.t = t.Clone ();
+ }
}
}

Modified: trunk/mcs/mcs/generic.cs
===================================================================
--- trunk/mcs/mcs/generic.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/generic.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -327,5 +327,10 @@
{
throw new NotImplementedException ();
}
+
+ public TypeArguments Clone ()
+ {
+ throw new NotImplementedException ();
+ }
}
}

Modified: trunk/mcs/mcs/lambda.cs
===================================================================
--- trunk/mcs/mcs/lambda.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/lambda.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -18,13 +18,6 @@
bool explicit_parameters;

//
- // If set, this was a lambda expression with an expression
- // argument. And if so, we have a pointer to it, so we can
- // change it if needed.
- //
- Expression lambda_expr;
-
- //
// The parameter list can either be:
// null: no parameters
// arraylist of Parameter (explicitly typed parameters)
@@ -41,11 +34,6 @@
Parameters = new Parameters (new Parameter [0]);
}

- public void SetExpression (Expression expr)
- {
- lambda_expr = expr;
- }
-
public override Expression DoResolve (EmitContext ec)
{
eclass = ExprClass.Value;
@@ -67,12 +55,45 @@
base.Emit (ec);
}

+ public override bool ImplicitStandardConversionExists (Type delegate_type)
+ {
+ EmitContext ec = EmitContext.TempEc;
+
+ bool result;
+
+ try {
+ Report.DisableErrors ();
+ result = Compatible (ec, delegate_type) != null;
+ } finally {
+ Report.EnableErrors ();
+ }
+
+ // Ignore the result
+ anonymous = null;
+
+ return result;
+ }
+
//
// Returns true if this anonymous method can be implicitly
// converted to the delegate type `delegate_type'
//
public override Expression Compatible (EmitContext ec, Type delegate_type)
{
+ Expression result;
+
+ result = DoCompatibleTest (ec, delegate_type);
+
+ if (result == null)
+ Console.WriteLine ("INFO: Lambda.Compatible Failed for {0}", delegate_type);
+ else
+ Console.WriteLine ("INFO: Lambda.Compatible Passed for {0}", delegate_type);
+
+ return result;
+ }
+
+ Expression DoCompatibleTest (EmitContext ec, Type delegate_type)
+ {
if (anonymous != null)
return anonymous.AnonymousDelegate;

@@ -94,7 +115,6 @@
if (Parameters.Count != invoke_pd.Count)
return null;

- Parameters parameters_copy = Parameters.Clone ();
if (explicit_parameters){
//
// If L has an explicitly typed parameter list, each parameter
@@ -103,8 +123,6 @@
//
if (!VerifyExplicitParameterCompatibility (delegate_type, invoke_pd))
return null;
-
- parameters_copy = Parameters.Clone ();
} else {
//
// If L has an implicitly typed parameter list, D has no ref or
@@ -118,9 +136,9 @@
//

for (int i = 0; i < invoke_pd.Count; i++)
- parameters_copy [i].TypeName = new TypeExpression (
+ Parameters [i].TypeName = new TypeExpression (
invoke_pd.ParameterType (i),
- parameters_copy [i].Location);
+ Parameters [i].Location);
}

//
@@ -130,9 +148,11 @@
// to be the delegate type return type.
//

+ ToplevelBlock b = (ToplevelBlock) Block.Clone ();
+
anonymous = new AnonymousMethod (
Parent != null ? Parent.AnonymousMethod : null, RootScope, Host,
- GenericMethod, parameters_copy, Container, Block, invoke_mb.ReturnType,
+ GenericMethod, Parameters, Container, b, invoke_mb.ReturnType,
delegate_type, loc);

if (!anonymous.Resolve (ec))
@@ -203,6 +223,12 @@
}
ec.ig.Emit (OpCodes.Ret);
}
-
+
+ protected override void CloneTo (Statement t)
+ {
+ ContextualReturn cr = (ContextualReturn) t;
+
+ cr.Expr = Expr.Clone ();
+ }
}
}

Modified: trunk/mcs/mcs/lambda.todo
===================================================================
--- trunk/mcs/mcs/lambda.todo 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/lambda.todo 2007-02-15 19:45:26 UTC (rev 72953)
@@ -16,4 +16,9 @@

* Generics section support.

-* Fix the bug in the modified l1.cs that introduces two rets
\ No newline at end of file
+* Fix the bug in the modified l1.cs that introduces two rets instead
+ of a single one.
+
+* Complete CloneTo for Statements.
+
+* Write an extensive test suite to exercise CloneTo
\ No newline at end of file

Modified: trunk/mcs/mcs/report.cs
===================================================================
--- trunk/mcs/mcs/report.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/report.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -64,6 +64,14 @@

static Hashtable warning_regions_table;

+ //
+ // This is used to save/restore the error state. When the
+ // error stack contains elements, warnings and errors are not
+ // reported to the user. This is used by the Lambda expression
+ // support to compile the code with various parameter values.
+ //
+ static Stack error_stack;
+
/// <summary>
/// List of symbols related to reported error/warning. You have to fill it before error/warning is reported.
/// </summary>
@@ -105,6 +113,18 @@
warning_regions_table = null;
}

+ public static void DisableErrors ()
+ {
+ if (error_stack == null)
+ error_stack = new Stack ();
+ error_stack.Push (Errors);
+ }
+
+ public static void EnableErrors ()
+ {
+ Errors = (int) error_stack.Pop ();
+ }
+
abstract class AbstractMessage {

static void Check (int code)
@@ -120,6 +140,9 @@

public virtual void Print (int code, string location, string text)
{
+ if (error_stack != null && error_stack.Count != 0)
+ return;
+
if (code < 0)
code = 8000-code;

Modified: trunk/mcs/mcs/statement.cs
===================================================================
--- trunk/mcs/mcs/statement.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/mcs/statement.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -85,7 +85,23 @@
{
ec.Mark (loc, true);
DoEmit (ec);
- }
+ }
+
+ //
+ // This routine must be overrided in derived classes and make copies
+ // of all the data that might be modified if resolved
+ //
+ protected virtual void CloneTo (Statement target)
+ {
+ throw new Exception (String.Format ("Statement.CloneTo not implemented for {0}", this.GetType ()));
+ }
+
+ public Statement Clone ()
+ {
+ Statement s = (Statement) this.MemberwiseClone ();
+ CloneTo (s);
+ return s;
+ }
}

public sealed class EmptyStatement : Statement {
@@ -569,6 +585,13 @@
{
return "StatementExpression (" + expr + ")";
}
+
+ protected override void CloneTo (Statement t)
+ {
+ StatementExpression target = (StatementExpression) t;
+
+ target.expr = (ExpressionStatement) expr.Clone ();
+ }
}

/// <summary>
@@ -646,6 +669,13 @@
else
ec.ig.Emit (OpCodes.Ret);
}
+
+ protected override void CloneTo (Statement t)
+ {
+ Return target = (Return) t;
+
+ target.Expr = Expr.Clone ();
+ }
}

public class Goto : Statement {
@@ -2273,6 +2303,25 @@
{
return String.Format ("{0} ({1}:{2})", GetType (),ID, StartLocation);
}
+
+ protected override void CloneTo (Statement t)
+ {
+ Block target = (Block) t;
+
+ target.statements = new ArrayList ();
+ foreach (Statement s in statements)
+ target.statements.Add (s.Clone ());
+
+ if (target.children != null){
+ target.children = new ArrayList ();
+ foreach (Block b in children)
+ target.children.Add (b.Clone ());
+ }
+
+ //
+ // TODO: labels, switch_block, variables, constants (?), anonymous_children
+ //
+ }
}

//
@@ -2621,6 +2670,7 @@
root_scope, anonymous_container != null ?
anonymous_container.Scope : null);
}
+
}

public class SwitchLabel {

Added: trunk/mcs/tests/ltest-2.cs
===================================================================
--- trunk/mcs/tests/ltest-2.cs 2007-02-15 19:45:03 UTC (rev 72952)
+++ trunk/mcs/tests/ltest-2.cs 2007-02-15 19:45:26 UTC (rev 72953)
@@ -0,0 +1,27 @@
+// Compiler options: -langversion:linq
+//
+// Lambda expression test overload resolution with parameterless arguments
+//
+
+using System;
+delegate string funcs (string s);
+delegate int funci (int i);
+
+class X {
+ static void Foo (funci fi)
+ {
+ int res = fi (10);
+ Console.WriteLine (res);
+ }
+
+ static void Foo (funcs fs)
+ {
+ string res = fs ("hello");
+ Console.WriteLine (res);
+ }
+
+ static void Main ()
+ {
+ Foo (x => x + "dingus");
+ }
+}


Property changes on: trunk/mcs/tests/ltest-2.cs
___________________________________________________________________
Name: svn:eol-style
+ native

Reply all
Reply to author
Forward
0 new messages