for (i = start, j = 0; i < count; i++, j++){
Expression name = (Expression) bases [i];
Expression resolved = ResolveTypeExpr (name, false, Location);
+ if (resolved == null)
+ return null;
+
bases [i] = resolved;
Type t = resolved.Type;
//
// Check for internal or private fields that were never assigned
//
- if (fields != null && RootContext.WarningLevel >= 3) {
- foreach (Field f in fields) {
- if ((f.ModFlags & Modifiers.PUBLIC) != 0)
- continue;
-
- if (f.status == 0){
+ if (RootContext.WarningLevel >= 3) {
+ if (fields != null){
+ foreach (Field f in fields) {
+ if ((f.ModFlags & Modifiers.PUBLIC) != 0)
+ continue;
+
+ if (f.status == 0){
+ Report.Warning (
+ 169, f.Location, "Private field " +
+ MakeName (f.Name) + " is never used");
+ continue;
+ }
+
+ //
+ // Only report 649 on level 4
+ //
+ if (RootContext.WarningLevel < 4)
+ continue;
+
+ if ((f.status & Field.Status.ASSIGNED) != 0)
+ continue;
+
Report.Warning (
- 169, f.Location, "Private field " +
- MakeName (f.Name) + " is never used");
- continue;
+ 649, f.Location,
+ "Field " + MakeName (f.Name) + " is never assigned " +
+ " to and will always have its default value");
}
+ }
- //
- // Only report 649 on level 4
- //
- if (RootContext.WarningLevel < 4)
- continue;
-
- if ((f.status & Field.Status.ASSIGNED) != 0)
- continue;
-
- Report.Warning (
- 649, f.Location,
- "Field " + MakeName (f.Name) + " is never assigned " +
- " to and will always have its default value");
+ if (events != null){
+ foreach (Event e in events){
+ if (e.status == 0)
+ Report.Warning (67, "The event " + MakeName (e.Name) + " is never used");
+ }
}
}
Type declaring_type, reflected_type, event_type;
string name;
- public MyEventBuilder (TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
+ Event my_event;
+
+ public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
{
MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
attributes = event_attr;
this.name = name;
+ my_event = ev;
this.event_type = event_type;
}
return event_type;
}
}
+
+ public void SetUsed ()
+ {
+ if (my_event != null)
+ my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
+ }
}
public class Event : FieldBase {
RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value");
if (!IsExplicitImpl){
- EventBuilder = new MyEventBuilder (
+ EventBuilder = new MyEventBuilder (this,
parent.TypeBuilder, Name, e_attr, MemberType);
if (Add == null && Remove == null) {
case "--linkres":
if ((i + 1) >= args.Length){
Usage ();
- Console.WriteLine("Missing argument to --linkres");
+ Report.Error (5, "Missing argument to --linkres");
Environment.Exit (1);
}
if (resources == null)
case "--res":
if ((i + 1) >= args.Length){
Usage ();
- Console.WriteLine("Missing argument to --resource");
+ Report.Error (5, "Missing argument to --resource");
Environment.Exit (1);
}
if (embedded_resources == null)
case "--mcs-debug":
if ((i + 1) >= args.Length){
- Console.WriteLine ("--mcs-debug requires an argument");
+ Report.Error (5, "--mcs-debug requires an argument");
Environment.Exit (1);
}
try {
Report.DebugFlags = Int32.Parse (args [++i]);
} catch {
- Console.WriteLine ("Invalid argument to --mcs-debug");
+ Report.Error (5, "Invalid argument to --mcs-debug");
Environment.Exit (1);
}
return true;
case "--recurse":
if ((i + 1) >= args.Length){
- Console.WriteLine ("--recurse requires an argument");
+ Report.Error (5, "--recurse requires an argument");
Environment.Exit (1);
}
CompileFiles (args [++i], true);
case "--debug-args":
if ((i + 1) >= args.Length){
- Console.WriteLine ("--debug-args requires an argument");
+ Report.Error (5, "--debug-args requires an argument");
Environment.Exit (1);
}
char[] sep = { ',' };
case "/linkres":
case "/linkresource":
if (value == ""){
- Console.WriteLine ("{0} requires an argument", arg);
+ Report.Error (5, arg + " requires an argument");
Environment.Exit (1);
}
if (resources == null)
case "/res":
case "/resource":
if (value == ""){
- Console.WriteLine ("{0} requires an argument", arg);
+ Report.Error (5, arg + " requires an argument");
Environment.Exit (1);
}
if (embedded_resources == null)
case "/recurse":
if (value == ""){
- Console.WriteLine ("/recurse requires an argument");
+ Report.Error (5, "/recurse requires an argument");
Environment.Exit (1);
}
CompileFiles (value, true);
case "/r":
case "/reference": {
if (value == ""){
- Console.WriteLine ("/reference requires an argument");
+ Report.Error (5, arg + " requires an argument");
Environment.Exit (1);
}
string [] libdirs;
if (value == ""){
- Console.WriteLine ("/lib requires an argument");
+ Report.Error (5, "/lib requires an argument");
Environment.Exit (1);
}
string [] warns;
if (value == ""){
- Console.WriteLine ("/nowarn requires an argument");
+ Report.Error (5, "/nowarn requires an argument");
Environment.Exit (1);
}
case "/main":
case "/m":
if (value == ""){
- Console.WriteLine ("/main requires an argument");
+ Report.Error (5, arg + " requires an argument");
Environment.Exit (1);
}
RootContext.MainClass = value;
/// for the common case, and one with the extra fields for more complex
/// classes (indexers require temporary access; overloaded require method)
///
- /// Maybe we should have classes PreIncrement, PostIncrement, PreDecrement,
- /// PostDecrement, that way we could save the `Mode' byte as well.
/// </remarks>
public class UnaryMutator : ExpressionStatement {
+ [Flags]
public enum Mode : byte {
- PreIncrement, PreDecrement, PostIncrement, PostDecrement
+ IsIncrement = 0,
+ IsDecrement = 1,
+ IsPre = 0,
+ IsPost = 2,
+
+ PreIncrement = 0,
+ PreDecrement = IsDecrement,
+ PostIncrement = IsPost,
+ PostDecrement = IsPost | IsDecrement
}
Mode mode;
}
//
- // Loads the proper "1" into the stack based on the type
+ // Loads the proper "1" into the stack based on the type, then it emits the
+ // opcode for the operation requested
//
- static void LoadOne (ILGenerator ig, Type t)
+ void LoadOneAndEmitOp (EmitContext ec, Type t)
{
+ ILGenerator ig = ec.ig;
+
if (t == TypeManager.uint64_type || t == TypeManager.int64_type)
- ig.Emit (OpCodes.Ldc_I8, 1L);
+ LongConstant.EmitLong (ig, 1);
else if (t == TypeManager.double_type)
ig.Emit (OpCodes.Ldc_R8, 1.0);
else if (t == TypeManager.float_type)
IntConstant.EmitInt (ig, n);
} else
ig.Emit (OpCodes.Ldc_I4_1);
+
+ //
+ // Now emit the operation
+ //
+ if (ec.CheckState){
+ if (t == TypeManager.int32_type ||
+ t == TypeManager.int64_type){
+ if ((mode & Mode.IsDecrement) != 0)
+ ig.Emit (OpCodes.Sub_Ovf);
+ else
+ ig.Emit (OpCodes.Add_Ovf);
+ } else if (t == TypeManager.uint32_type ||
+ t == TypeManager.uint64_type){
+ if ((mode & Mode.IsDecrement) != 0)
+ ig.Emit (OpCodes.Sub_Ovf_Un);
+ else
+ ig.Emit (OpCodes.Add_Ovf_Un);
+ } else {
+ if ((mode & Mode.IsDecrement) != 0)
+ ig.Emit (OpCodes.Sub_Ovf);
+ else
+ ig.Emit (OpCodes.Add_Ovf);
+ }
+ } else {
+ if ((mode & Mode.IsDecrement) != 0)
+ ig.Emit (OpCodes.Sub);
+ else
+ ig.Emit (OpCodes.Add);
+ }
}
-
- //
- // FIXME: We need some way of avoiding the use of temp_storage
- // for some types of storage (parameters, local variables,
- // static fields) and single-dimension array access.
- //
void EmitCode (EmitContext ec, bool is_expr)
{
ILGenerator ig = ec.ig;
IAssignMethod ia = (IAssignMethod) expr;
Type expr_type = expr.Type;
-
- if (temp_storage == null)
- temp_storage = new LocalTemporary (ec, expr_type);
ia.CacheTemporaries (ec);
- ig.Emit (OpCodes.Nop);
+
+ if (temp_storage == null)
+ temp_storage = new LocalTemporary (ec, expr_type);
+
switch (mode){
case Mode.PreIncrement:
case Mode.PreDecrement:
if (method == null){
expr.Emit (ec);
-
- LoadOne (ig, expr_type);
- //
- // Select the opcode based on the check state (then the type)
- // and the actual operation
- //
- if (ec.CheckState){
- if (expr_type == TypeManager.int32_type ||
- expr_type == TypeManager.int64_type){
- if (mode == Mode.PreDecrement)
- ig.Emit (OpCodes.Sub_Ovf);
- else
- ig.Emit (OpCodes.Add_Ovf);
- } else if (expr_type == TypeManager.uint32_type ||
- expr_type == TypeManager.uint64_type){
- if (mode == Mode.PreDecrement)
- ig.Emit (OpCodes.Sub_Ovf_Un);
- else
- ig.Emit (OpCodes.Add_Ovf_Un);
- } else {
- if (mode == Mode.PreDecrement)
- ig.Emit (OpCodes.Sub_Ovf);
- else
- ig.Emit (OpCodes.Add_Ovf);
- }
- } else {
- if (mode == Mode.PreDecrement)
- ig.Emit (OpCodes.Sub);
- else
- ig.Emit (OpCodes.Add);
- }
+ LoadOneAndEmitOp (ec, expr_type);
} else
method.Emit (ec);
-
+
temp_storage.Store (ec);
ia.EmitAssign (ec, temp_storage);
if (is_expr)
expr.Emit (ec);
else
ig.Emit (OpCodes.Dup);
-
- LoadOne (ig, expr_type);
- if (ec.CheckState){
- if (expr_type == TypeManager.int32_type ||
- expr_type == TypeManager.int64_type){
- if (mode == Mode.PostDecrement)
- ig.Emit (OpCodes.Sub_Ovf);
- else
- ig.Emit (OpCodes.Add_Ovf);
- } else if (expr_type == TypeManager.uint32_type ||
- expr_type == TypeManager.uint64_type){
- if (mode == Mode.PostDecrement)
- ig.Emit (OpCodes.Sub_Ovf_Un);
- else
- ig.Emit (OpCodes.Add_Ovf_Un);
- } else {
- if (mode == Mode.PostDecrement)
- ig.Emit (OpCodes.Sub_Ovf);
- else
- ig.Emit (OpCodes.Add_Ovf);
- }
- } else {
- if (mode == Mode.PostDecrement)
- ig.Emit (OpCodes.Sub);
- else
- ig.Emit (OpCodes.Add);
- }
+ LoadOneAndEmitOp (ec, expr_type);
} else {
method.Emit (ec);
}
return;
case Action.AlwaysTrue:
ig.Emit (OpCodes.Pop);
- ig.Emit (OpCodes.Nop);
IntConstant.EmitInt (ig, 1);
return;
case Action.LeaveOnStack:
left.Emit (ec);
right.Emit (ec);
+ bool isUnsigned = is_unsigned (left.Type);
switch (oper){
case Operator.Multiply:
if (ec.CheckState){
if (l == TypeManager.int32_type || l == TypeManager.int64_type)
opcode = OpCodes.Mul_Ovf;
- else if (l==TypeManager.uint32_type || l==TypeManager.uint64_type)
+ else if (isUnsigned)
opcode = OpCodes.Mul_Ovf_Un;
else
opcode = OpCodes.Mul;
break;
case Operator.Division:
- if (l == TypeManager.uint32_type || l == TypeManager.uint64_type)
+ if (isUnsigned)
opcode = OpCodes.Div_Un;
else
opcode = OpCodes.Div;
break;
case Operator.Modulus:
- if (l == TypeManager.uint32_type || l == TypeManager.uint64_type)
+ if (isUnsigned)
opcode = OpCodes.Rem_Un;
else
opcode = OpCodes.Rem;
if (ec.CheckState){
if (l == TypeManager.int32_type || l == TypeManager.int64_type)
opcode = OpCodes.Add_Ovf;
- else if (l==TypeManager.uint32_type || l==TypeManager.uint64_type)
+ else if (isUnsigned)
opcode = OpCodes.Add_Ovf_Un;
else
opcode = OpCodes.Add;
if (ec.CheckState){
if (l == TypeManager.int32_type || l == TypeManager.int64_type)
opcode = OpCodes.Sub_Ovf;
- else if (l==TypeManager.uint32_type || l==TypeManager.uint64_type)
+ else if (isUnsigned)
opcode = OpCodes.Sub_Ovf_Un;
else
opcode = OpCodes.Sub;
break;
case Operator.RightShift:
- if (l == TypeManager.uint32_type || l == TypeManager.uint64_type)
+ if (isUnsigned)
opcode = OpCodes.Shr_Un;
else
opcode = OpCodes.Shr;
break;
case Operator.Inequality:
- ec.ig.Emit (OpCodes.Ceq);
- ec.ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Ceq);
+ ig.Emit (OpCodes.Ldc_I4_0);
opcode = OpCodes.Ceq;
break;
case Operator.LessThan:
- opcode = OpCodes.Clt;
+ if (isUnsigned)
+ opcode = OpCodes.Clt_Un;
+ else
+ opcode = OpCodes.Clt;
break;
case Operator.GreaterThan:
- opcode = OpCodes.Cgt;
+ if (isUnsigned)
+ opcode = OpCodes.Cgt_Un;
+ else
+ opcode = OpCodes.Cgt;
break;
case Operator.LessThanOrEqual:
- ec.ig.Emit (OpCodes.Cgt);
- ec.ig.Emit (OpCodes.Ldc_I4_0);
+ if (isUnsigned)
+ ig.Emit (OpCodes.Cgt_Un);
+ else
+ ig.Emit (OpCodes.Cgt);
+ ig.Emit (OpCodes.Ldc_I4_0);
opcode = OpCodes.Ceq;
break;
case Operator.GreaterThanOrEqual:
- ec.ig.Emit (OpCodes.Clt);
- ec.ig.Emit (OpCodes.Ldc_I4_1);
+ if (isUnsigned)
+ ig.Emit (OpCodes.Clt_Un);
+ else
+ ig.Emit (OpCodes.Clt);
+
+ ig.Emit (OpCodes.Ldc_I4_1);
opcode = OpCodes.Sub;
break;
ec.ig.Emit (OpCodes.Ldarga, arg_idx);
}
}
+
}
/// <summary>