+2002-01-24 Miguel de Icaza <miguel@ximian.com>
+
+ * statement.cs (Do.Emit, While.Emit, For.Emit,
+ Statement.EmitBoolExpression): Add support to Do and While to
+ propagate infinite loop as `I do return' semantics.
+
+ Improve the For case to also test for boolean constants.
+
+ * attribute.cs (Attribute.ApplyAttributes): Add ParameterBuilder
+ to the list of attributes we can add.
+
+ Remove `EmitContext' argument.
+
+ * class.cs (Method.Define): Apply parameter attributes.
+ (Constructor.Define): Apply parameter attributes.
+ (MethodCore.LabelParameters): Move here the core of labeling
+ parameters.
+
+ * support.cs (ReflectionParameters.ParameterModifier,
+ InternalParameters.ParameterModifier): Use IsByRef on the type and
+ only return the OUT bit for these parameters instead of in/out/ref
+ flags.
+
+ This is because I miss-understood things. The ParameterInfo.IsIn
+ and IsOut represent whether the parameter has the [In] and [Out]
+ attributes set.
+
2002-01-22 Miguel de Icaza <miguel@ximian.com>
* ecore.cs (FieldExpr.Emit): Release temporaries.
\r
public static void error592 (Attribute a, Location loc)\r
{\r
- Report.Error (592, loc, "Attribute '" + a.Name + "' is not valid on this declaration type. " +\r
- "It is valid on " + GetValidPlaces (a) + "declarations only.");\r
+ Report.Error (\r
+ 592, loc, "Attribute '" + a.Name +\r
+ "' is not valid on this declaration type. " +\r
+ "It is valid on " + GetValidPlaces (a) + "declarations only.");\r
}\r
\r
public static bool CheckAttribute (Attribute a, object element)\r
return true;\r
else\r
return false;\r
- } else if (element is Parameter) {\r
+ } else if (element is ParameterBuilder) {\r
if ((targets & AttributeTargets.Parameter) != 0)\r
return true;\r
else\r
return true;\r
else\r
return false;\r
- }\r
+ } \r
\r
return false;\r
}\r
\r
if (!(kind is TypeContainer))\r
if (!CheckAttribute (a, kind)) {\r
+ Console.WriteLine ("Kind is: " + kind);\r
error592 (a, loc);\r
return;\r
}\r
\r
} else if (kind is Constructor) {\r
((ConstructorBuilder) builder).SetCustomAttribute (cb);\r
-\r
} else if (kind is Field) {\r
((FieldBuilder) builder).SetCustomAttribute (cb);\r
-\r
} else if (kind is Property || kind is Indexer) {\r
((PropertyBuilder) builder).SetCustomAttribute (cb);\r
-\r
} else if (kind is Event) {\r
((EventBuilder) builder).SetCustomAttribute (cb);\r
-\r
+ } else if (kind is ParameterBuilder){\r
+ ((ParameterBuilder) builder).SetCustomAttribute (cb);\r
} else if (kind is Operator) {\r
((MethodBuilder) builder).SetCustomAttribute (cb);\r
-\r
} else if (kind is Enum) {\r
((TypeBuilder) builder).SetCustomAttribute (cb); \r
\r
return cc;
}
+
+ public void LabelParameters (EmitContext ec, Type [] parameters, MethodBase builder)
+ {
+ //
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ //
+ Parameter [] p = Parameters.FixedParameters;
+ if (p == null)
+ return;
+
+ MethodBuilder mb = null;
+ ConstructorBuilder cb = null;
+
+ if (builder is MethodBuilder)
+ mb = (MethodBuilder) builder;
+ else
+ cb = (ConstructorBuilder) builder;
+
+ int i;
+
+ for (i = 0; i < p.Length; i++) {
+ ParameterBuilder pb;
+
+ if (mb == null)
+ pb = cb.DefineParameter (
+ i + 1, p [i].Attributes, p [i].Name);
+ else
+ pb = mb.DefineParameter (
+ i + 1, p [i].Attributes, p [i].Name);
+
+ Attributes attr = p [i].OptAttributes;
+ if (attr != null)
+ Attribute.ApplyAttributes (ec, pb, pb, attr, Location);
+ }
+
+ if (i != parameters.Length) {
+ ParameterBuilder pb;
+
+ Parameter array_param = Parameters.ArrayParameter;
+ if (mb == null)
+ pb = cb.DefineParameter (
+ i + 1, array_param.Attributes,
+ array_param.Name);
+ else
+ pb = mb.DefineParameter (
+ i + 1, array_param.Attributes,
+ array_param.Name);
+
+ CustomAttributeBuilder a = new CustomAttributeBuilder (
+ TypeManager.cons_param_array_attribute, new object [0]);
+
+ pb.SetCustomAttribute (a);
+ }
+ }
}
public class Method : MethodCore {
// error 28 if not.
//
}
-
- //
- // Define each type attribute (in/out/ref) and
- // the argument names.
- //
- Parameter [] p = Parameters.FixedParameters;
- if (p != null){
- int i;
-
- for (i = 0; i < p.Length; i++)
- MethodBuilder.DefineParameter (
- i + 1, p [i].Attributes, p [i].Name);
-
- if (i != parameters.Length) {
- ParameterBuilder pb;
-
- Parameter array_param = Parameters.ArrayParameter;
- pb = MethodBuilder.DefineParameter (
- i + 1, array_param.Attributes,
- array_param.Name);
-
- CustomAttributeBuilder a = new CustomAttributeBuilder (
- TypeManager.cons_param_array_attribute, new object [0]);
-
- pb.SetCustomAttribute (a);
- }
- }
return true;
}
EmitContext ec = new EmitContext (parent, Location, ig,
GetReturnType (parent), ModFlags);
- Attribute.ApplyAttributes (ec, MethodBuilder, this, OptAttributes, Location);
+ if (OptAttributes != null)
+ Attribute.ApplyAttributes (ec, MethodBuilder, this, OptAttributes, Location);
+
+ LabelParameters (ec, ParameterTypes (parent), MethodBuilder);
//
// abstract or extern methods have no bodies
+ "'");
return false;
}
-
+
return true;
}
}
}
+ LabelParameters (ec, ParameterTypes (parent), ConstructorBuilder);
+
//
// Classes can have base initializers and instance field initializers.
//
public Parameter.Modifier GetParameterModifier ()
{
- if (ArgType == AType.Ref)
- return Parameter.Modifier.REF;
-
- if (ArgType == AType.Out)
+ if (ArgType == AType.Ref || ArgType == AType.Out)
return Parameter.Modifier.OUT;
return Parameter.Modifier.NONE;
if (a.GetParameterModifier () != pd.ParameterModifier (j) &&
pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS) {
if (!Location.IsNull (loc)) {
+ Console.WriteLine ("A:P: " + a.GetParameterModifier ());
+ Console.WriteLine ("PP:: " + pd.ParameterModifier (j));
+ Console.WriteLine ("PT: " + parameter_type.IsByRef);
Error (1502, loc,
"The best overloaded match for method '" + FullMethodDesc (method)+
"' has some invalid arguments");
/// <remarks>
/// Emits a bool expression.
/// </remarks>
- public static bool EmitBoolExpression (EmitContext ec, Expression e, Label l, bool isTrue)
+ public static Expression EmitBoolExpression (EmitContext ec, Expression e,
+ Label l, bool isTrue)
{
e = e.Resolve (ec);
if (e == null)
- return false;
+ return null;
if (e.Type != TypeManager.bool_type)
e = Expression.ConvertImplicit (ec, e, TypeManager.bool_type,
if (e == null){
Report.Error (
31, "Can not convert the expression to a boolean");
- return false;
+ return null;
}
bool invert = false;
ec.ig.Emit (OpCodes.Brfalse, l);
}
- return true;
+ return e;
}
}
Label end;
bool is_true_ret, is_false_ret;
- if (!EmitBoolExpression (ec, Expr, false_target, false))
+ if (EmitBoolExpression (ec, Expr, false_target, false) == null)
return false;
is_true_ret = TrueStatement.Emit (ec);
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ Expression e;
ec.LoopBegin = ig.DefineLabel ();
ec.LoopEnd = ig.DefineLabel ();
ig.MarkLabel (loop);
EmbeddedStatement.Emit (ec);
ig.MarkLabel (ec.LoopBegin);
- EmitBoolExpression (ec, Expr, loop, true);
+ e = EmitBoolExpression (ec, Expr, loop, true);
ig.MarkLabel (ec.LoopEnd);
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+
+ //
+ // Inform whether we are infinite or not
+ //
+ if (e is BoolConstant){
+ BoolConstant bc = (BoolConstant) e;
+
+ if (bc.Value == true)
+ return true;
+ }
return false;
}
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ Expression e;
ec.LoopBegin = ig.DefineLabel ();
ec.LoopEnd = ig.DefineLabel ();
ec.InLoop = true;
ig.MarkLabel (ec.LoopBegin);
- EmitBoolExpression (ec, Expr, ec.LoopEnd, false);
+ e = EmitBoolExpression (ec, Expr, ec.LoopEnd, false);
Statement.Emit (ec);
ig.Emit (OpCodes.Br, ec.LoopBegin);
ig.MarkLabel (ec.LoopEnd);
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
-
+
+ //
+ // Inform whether we are infinite or not
+ //
+ if (e is BoolConstant){
+ BoolConstant bc = (BoolConstant) e;
+
+ if (bc.Value == true)
+ return true;
+ }
return false;
}
}
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
Label loop = ig.DefineLabel ();
+ Expression e = null;
if (InitStatement != null)
if (! (InitStatement is EmptyStatement))
// an infinite loop
//
if (Test != null)
- EmitBoolExpression (ec, Test, ec.LoopEnd, false);
+ e = EmitBoolExpression (ec, Test, ec.LoopEnd, false);
Statement.Emit (ec);
ig.MarkLabel (ec.LoopBegin);
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
- return Test == null;
+ //
+ // Inform whether we are infinite or not
+ //
+ if (Test != null){
+ if (e is BoolConstant){
+ BoolConstant bc = (BoolConstant) e;
+
+ if (bc.Value)
+ return true;
+ }
+ return false;
+ } else
+ return true;
}
}
if (last_arg_is_params)
return Parameter.Modifier.PARAMS;
- if (pi [pos].IsOut)
+ Type t = pi [pos].ParameterType;
+ if (t.IsByRef)
return Parameter.Modifier.OUT;
return Parameter.Modifier.NONE;
{
if (pos >= parameters.FixedParameters.Length)
return parameters.ArrayParameter.ModFlags;
- else
- return parameters.FixedParameters [pos].ModFlags;
+ else {
+ Parameter.Modifier m = parameters.FixedParameters [pos].ModFlags;
+
+ //
+ // We use a return value of "OUT" for "reference" parameters.
+ // both out and ref flags in the source map to reference parameters.
+ //
+ if (m == Parameter.Modifier.OUT || m == Parameter.Modifier.REF)
+ return Parameter.Modifier.OUT;
+
+ return Parameter.Modifier.NONE;
+ }
}
}