//
// TODO:
// Flow analysis for Yield.
-// Emit calls to parent object constructor.
+// Emit calls to base object constructor.
//
// Generics note:
// Current should be defined to return T, and IEnumerator.Current returns object
public static bool CheckContext (EmitContext ec, Location loc)
{
- if (ec.CurrentBranching.InFinally (true)){
+ if (ec.InFinally) {
Report.Error (1625, loc, "Cannot yield in the body of a " +
"finally clause");
return false;
+ }
+
+ if (ec.InUnsafe) {
+ Report.Error (1629, loc, "Unsafe code may not appear in iterators");
+ return false;
}
- if (ec.CurrentBranching.InCatch ()){
+ if (ec.InCatch){
Report.Error (1631, loc, "Cannot yield in the body of a " +
"catch clause");
return false;
}
if (ec.CurrentAnonymousMethod != null){
- Report.Error (1621, loc, "yield statement can not appear inside an anonymoud method");
+ Report.Error (1621, loc, "The yield statement cannot be used inside anonymous method blocks");
return false;
}
- //
- // FIXME: Missing check for Yield inside try block that contains catch clauses
- //
+ if (ec.CurrentBranching.InTryWithCatch ()) {
+ Report.Error (1626, loc, "Cannot yield a value in the body of a " +
+ "try block with a catch clause");
+ return false;
+ }
return true;
}
//
TypeContainer container;
Type return_type;
- Type [] param_types;
InternalParameters parameters;
protected enum State {
// Our constructor
//
public Iterator (TypeContainer container, string name, Type return_type,
- Type [] param_types, InternalParameters parameters,
+ InternalParameters parameters,
int modifiers, ToplevelBlock block, Location loc)
: base (container.NamespaceEntry, container, MakeProxyName (name),
- Modifiers.PRIVATE, null, loc)
+ (modifiers & Modifiers.UNSAFE) | Modifiers.PRIVATE, null, loc)
{
this.container = container;
this.return_type = return_type;
- this.param_types = param_types;
this.parameters = parameters;
this.original_name = name;
this.original_block = block;
"Iterators cannot have ref or out parameters");
return false;
}
+
+ if ((mod & Parameter.Modifier.ARGLIST) != 0) {
+ Report.Error (1636, Location, "__arglist is not allowed in parameter list of iterators");
+ return false;
+ }
+
+ if (parameters.ParameterType (i).IsPointer) {
+ Report.Error (1637, Location, "Iterators cannot have unsafe parameters or yield types");
+ return false;
+ }
}
ArrayList list = new ArrayList ();
if (!is_static)
list.Add (new Parameter (
new TypeExpression (container.TypeBuilder, Location),
- "this", Parameter.Modifier.NONE, null));
+ "this", Parameter.Modifier.NONE,
+ null, Location));
list.Add (new Parameter (
TypeManager.system_boolean_expr, "initialized",
- Parameter.Modifier.NONE, null));
+ Parameter.Modifier.NONE, null, Location));
Parameter[] old_fixed = parameters.Parameters.FixedParameters;
if (old_fixed != null)
list.CopyTo (fixed_params);
ctor_params = new Parameters (
- fixed_params, parameters.Parameters.ArrayParameter,
- Location);
+ fixed_params, parameters.Parameters.ArrayParameter);
Constructor ctor = new Constructor (
this, Name, Modifiers.PUBLIC, ctor_params,
this.field = field;
}
+ public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+ {
+ return DoResolve (ec);
+ }
+
public override Expression DoResolve (EmitContext ec)
{
FieldExpr fexpr = new FieldExpr (field.FieldBuilder, loc);
if (iterator.is_static)
code_flags |= Modifiers.STATIC;
+ code_flags |= iterator.ModFlags & Modifiers.UNSAFE;
+
EmitContext new_ec = new EmitContext (
iterator.container, loc, ec.ig,
TypeManager.int32_type, code_flags);