[svn] r7113: nemerle/trunk/ncc: generation/DecisionTreeCompiler.n
generation/ILEmitter.n typing/DecisionTr...
nazgul
svnadmin at nemerle.org
Sun Dec 17 22:11:38 CET 2006
Log:
Improve generated debug information
Author: nazgul
Date: Sun Dec 17 22:11:31 2006
New Revision: 7113
Modified:
nemerle/trunk/ncc/generation/DecisionTreeCompiler.n
nemerle/trunk/ncc/generation/ILEmitter.n
nemerle/trunk/ncc/typing/DecisionTreeBuilder.n
nemerle/trunk/ncc/typing/Typer2.n
Modified: nemerle/trunk/ncc/generation/DecisionTreeCompiler.n
==============================================================================
--- nemerle/trunk/ncc/generation/DecisionTreeCompiler.n (original)
+++ nemerle/trunk/ncc/generation/DecisionTreeCompiler.n Sun Dec 17 22:11:31 2006
@@ -55,7 +55,7 @@
public GetExpr () : TExpr
{
match (label_id) {
- | Some (id) => TExpr.Goto (id, 1);
+ | Some (id) => TExpr.Goto (body.Location, null, id, 1);
| None =>
def id = Util.next_id (body.Type.Manager);
label_id = Some (id);
@@ -173,7 +173,7 @@
TExpr.Goto (id, 1)
}
- | _ => compile2 (decision)
+ | _ => Util.locate (decision.Location, compile2 (decision))
}
@@ -245,7 +245,9 @@
// the VM stack
build_path_expression (path : Path) : TExpr
{
- | Here => val
+ | Here =>
+ val.loc = Location.Default; // try to not confuse debugger with back reference location
+ val
| Field (f, p) =>
def p_expr = get_path_expression (p);
@@ -425,7 +427,7 @@
static If (cond : TExpr, e1 : TExpr, e2 : TExpr) : TExpr
{
- TExpr.If (cond.Location, e1.Type, cond, e1, e2)
+ TExpr.If (Location.Default, e1.Type, cond, e1, e2)
}
static Cast (expr : TExpr, ty : TyVar) : TExpr
Modified: nemerle/trunk/ncc/generation/ILEmitter.n
==============================================================================
--- nemerle/trunk/ncc/generation/ILEmitter.n (original)
+++ nemerle/trunk/ncc/generation/ILEmitter.n Sun Dec 17 22:11:31 2006
@@ -139,9 +139,9 @@
_method_start_label = _ilg.DefineLabel ();
_ilg.MarkLabel (_method_start_label);
+ Mark (_fun_header.Location);
match (_fun_header.body) {
| FunBody.Typed (body) =>
- Mark (body.loc);
emit (body);
unless (body.Throws)
_ilg.Emit (OpCodes.Ret);
@@ -580,7 +580,9 @@
/* emits the if/then/else construction */
| If (cond_expr, then_expr, else_expr) =>
+ Mark (cond_expr.loc);
def emit_branch (expr : TExpr, else_label : Label) {
+ Mark (expr.loc);
match (expr) {
| Call (OpCode (opcode), parms, _) =>
emit_parms (parms);
@@ -605,12 +607,10 @@
| _ => Util.ice ("invalid opcode '" + opcode +
"' in optimized TExpr.If pattern")
};
- Mark (expr.loc);
_ilg.Emit (opcode, else_label);
| HasType (val, ty) =>
emit (val);
- Mark (expr.loc);
need_reference (val.SystemType);
_ilg.Emit (OpCodes.Isinst, ty.SystemType);
_ilg.Emit (OpCodes.Brfalse, else_label);
@@ -628,14 +628,12 @@
| e when is_always_true (e) => ()
| e when is_always_false (e) =>
- Mark (e.loc);
_ilg.Emit (OpCodes.Br, else_label);
| _ =>
//Message.Debug (e.loc, pretty_print (e));
// most of other expressions here are TExpr.Ref
emit (expr);
- Mark (cond_expr.loc);
unless (expr.Throws)
_ilg.Emit (OpCodes.Brfalse, else_label);
}
@@ -784,12 +782,12 @@
_ilg.Emit (OpCodes.Unbox_Any, cast_to_type.SystemType);
| TypeConversion (ignored, ty, _) when is_void (ty) =>
+ Mark (expr.loc);
// a little trickery, so emit can be tail called sometimes
if (is_void (ignored.Type))
emit (ignored)
else {
emit (ignored);
- Mark (expr.loc);
_ilg.Emit (OpCodes.Pop);
}
@@ -829,9 +827,9 @@
/* unbox value types or perform value type conversion */
| TypeConversion (val, cast_to_type, kind) =>
+ Mark (expr.loc);
def is_checked = ! (kind is IL (false));
emit (val);
- Mark (expr.loc);
def type_of_expr = val.SystemType;
def cast_to_stype = cast_to_type.SystemType;
@@ -910,12 +908,12 @@
/* load an array element */
| ArrayIndexer (array_obj, [index]) =>
+ Mark (expr.loc);
emit (array_obj);
emit (index);
def element_type = array_obj.SystemType.GetElementType ();
assert (element_type != null, "non-array in TExpr.ArrayIndexer");
- Mark (expr.loc);
if (expr.NeedAddress)
_ilg.Emit (OpCodes.Ldelema, element_type)
else
@@ -923,9 +921,9 @@
| ArrayIndexer (array_obj, indexes) =>
+ Mark (expr.loc);
emit (array_obj);
List.Iter (indexes, emit);
- Mark (expr.loc);
def method =
if (expr.NeedAddress) array_addr_method (array_obj)
else array_get_method (array_obj);
@@ -948,9 +946,9 @@
/* assignment to ref/out parameter */
| Assign (LocalRef (local_var), val) when local_var.IsByRefParm =>
+ Mark (expr.loc);
emit_ldarg (local_var.ParmIndex);
emit (val);
- Mark (expr.loc);
def ty = val.SystemType;
if (ty.IsValueType || ty.IsGenericParameter)
_ilg.Emit (OpCodes.Stobj, ty)
@@ -960,17 +958,17 @@
/* assignment to a local variable */
| Assign (LocalRef (local_var), val) =>
- emit (val);
Mark (expr.loc);
+ emit (val);
unless (val.Throws)
store_local (local_var);
/* assignment to a field */
| Assign (FieldMember (base_object, field) as target, val) =>
+ Mark (expr.loc);
emit (base_object);
emit (val);
- Mark (expr.loc);
maybe_volatile (target);
def field_info = GetFieldInfo (base_object, field);
@@ -980,8 +978,8 @@
/* assignment to a static field */
| Assign (StaticRef (t, f is IField, _) as target, val) =>
- emit (val);
Mark (expr.loc);
+ emit (val);
maybe_volatile (target);
def field_info = GetFieldInfo (t.SystemType, f);
@@ -991,11 +989,11 @@
/* assignment to an array element */
| Assign (ArrayIndexer (array_obj, [index]) as target, val) =>
+ Mark (expr.loc);
def type_of_val = val.SystemType;
emit (array_obj);
emit (index);
- Mark (expr.loc);
when (type_of_val.IsValueType && !type_of_val.IsPrimitive)
_ilg.Emit (OpCodes.Ldelema, type_of_val);
@@ -1003,10 +1001,10 @@
emit_array_store_opcode (target.SystemType);
| Assign (ArrayIndexer (array_obj, indexes), val) =>
+ Mark (expr.loc);
emit (array_obj);
List.Iter (indexes, emit);
emit (val);
- Mark (expr.loc);
def method = array_set_method (array_obj);
emit_method_call (expr, true, method);
@@ -1033,9 +1031,9 @@
/* call the base constructor */
| Call (Base (base_ctor), ctor_params, _) =>
+ Mark (expr.loc);
_ilg.Emit (OpCodes.Ldarg_0);
emit_parms (ctor_params);
- Mark (expr.loc);
def from =
if (base_ctor.DeclaringType.Equals (_parent_type_builder))
@@ -1049,8 +1047,8 @@
/* create a new object */
| Call (StaticRef (_t, meth is IMethod, _), ctor_params, _) when is_ctor (meth) =>
- emit_parms (ctor_params);
Mark (expr.loc);
+ emit_parms (ctor_params);
def ctr_inf = GetConstructorInfo (_t.SystemType, meth);
_ilg.Emit (OpCodes.Newobj, ctr_inf);
@@ -1061,6 +1059,7 @@
/* emit a call to an instance method, basing on the 'this' pointer for value types */
| Call (MethodRef (This as th, method, tparms, _), method_params, _)
when _this_is_value_type =>
+ Mark (expr.loc);
_ilg.Emit (OpCodes.Ldarg_0);
def method_inf = GetMethodInfo (th.Type, method, tparms);
@@ -1072,18 +1071,17 @@
_ilg.Emit (OpCodes.Box, _type_of_this);
}
emit_parms (method_params);
- Mark (expr.loc);
emit_method_call (expr, true, method_inf, method, th.MType)
/* emit a call to an instance method */
| Call (MethodRef (base_object, method, tparms, notvirt), method_params, _) =>
+ Mark (expr.loc);
def is_value_type = emit_and_convert_to_address (base_object);
def method_inf = GetMethodInfo (base_object.Type, method, tparms);
emit_parms (method_params);
- Mark (expr.loc);
if (base_object.NeedsConstrained) {
def is_tail = expr.GenerateTail;
@@ -1101,21 +1099,21 @@
/* emit a call to a static method */
| Call (StaticRef (_t, mi is IMethod, tparms), method_parms, _) =>
+ Mark (expr.loc);
def method_info = GetMethodInfo (_t, mi, tparms);
Util.cassert (method_info.IsStatic,
$ "Call TExpr.GlobalRef to a non-static field: $(method_info.Name)");
emit_parms (method_parms);
- Mark (expr.loc);
emit_method_call (expr, true, method_info, mi, _t)
/* emit an operator */
| Call (OpCode (opcode), parms, _) =>
+ Mark (expr.loc);
// FIXME: seperate out
emit_parms (parms);
- Mark (expr.loc);
match (opcode) {
| "+.s" => _ilg.Emit (OpCodes.Add_Ovf)
| "+.u" => _ilg.Emit (OpCodes.Add_Ovf_Un)
@@ -1246,8 +1244,8 @@
_ilg.Emit (OpCodes.Rethrow);
| Throw (exc) =>
- emit (exc);
Mark (expr.loc);
+ emit (exc);
_ilg.Emit (OpCodes.Throw);
@@ -1425,6 +1423,7 @@
/* creates a new array, given a list of initializers */
| Array (initializers, [size]) =>
+ Mark (expr.loc);
def element_type =
match (expr.Type.Fix ()) {
| MType.Array (t, _) => t.SystemType
@@ -1432,7 +1431,6 @@
}
emit (size);
- Mark (expr.loc);
_ilg.Emit (OpCodes.Newarr, element_type);
def load_elements (index : int, elements : list [TExpr]) {
@@ -1453,6 +1451,7 @@
load_elements (0, initializers);
| Array (initializers, dimensions) =>
+ Mark (expr.loc);
mutable size = 0;
foreach (element in dimensions) {
++size;
@@ -1466,7 +1465,6 @@
_module_builder.GetArrayMethod (expr.SystemType, ".ctor",
CallingConventions.HasThis,
null, arg_types);
- Mark (expr.loc);
_ilg.Emit (OpCodes.Newobj, method);
unless (initializers.IsEmpty) {
Modified: nemerle/trunk/ncc/typing/DecisionTreeBuilder.n
==============================================================================
--- nemerle/trunk/ncc/typing/DecisionTreeBuilder.n (original)
+++ nemerle/trunk/ncc/typing/DecisionTreeBuilder.n Sun Dec 17 22:11:31 2006
@@ -483,6 +483,9 @@
[Accessor (flags = WantSetter)]
mutable in_deg : int;
+ [Accessor]
+ mutable location : Location;
+
public IsShared : bool
{
get { in_deg > 1 }
@@ -493,10 +496,11 @@
[Accessor (flags = WantSetter)]
mutable label_id : option [int];
- public this ()
+ public this (loc : Location)
{
in_deg = 0;
- label_id = None ()
+ label_id = None ();
+ this.location = loc;
}
// this equality test is used for bottom-up detection of shared
@@ -554,7 +558,7 @@
BuildFailure () : Decision
{
match (continuation) {
- | [] => Decision.Failure ()
+ | [] => Decision.Failure (Location.Default)
| (pat, has_guard, res_id) :: rest =>
def p = TopLevelPattern (has_guard, res_id, rest, skel, nodes);
p.Build ([(Path.Here (pat.Type), skel, pat)])
@@ -567,11 +571,11 @@
BuildSuccess () : Decision
{
if (has_guard)
- Decision.IfEq (Path.Here (), Con.Guard (),
- Decision.Success (res_id),
+ Decision.IfEq (Location.Default, Path.Here (), Con.Guard (),
+ Decision.Success (Location.Default, res_id),
BuildFailure ())
else
- Decision.Success (res_id)
+ Decision.Success (Location.Default, res_id)
}
@@ -616,7 +620,7 @@
def if_false = BuildFailure ();
skel.Restore (state);
- Decision.IfEq (path, con, if_true, if_false)
+ Decision.IfEq (pat.Location, path, con, if_true, if_false)
}
}
@@ -646,14 +650,14 @@
if (check_resid (dtree))
match (dtree)
{
- | Decision.IfEq (_, Con.Guard, _, _) => Decision.Assign (path, decl, dtree)
+ | Decision.IfEq (_, Con.Guard, _, _) => Decision.Assign (dtree.Location, path, decl, dtree)
| Decision.IfEq (p, con, if_true, if_false) =>
- def assign = Decision.Assign (path, decl, if_true);
- Decision.IfEq (p, con, assign, if_false);
+ def assign = Decision.Assign (dtree.Location, path, decl, if_true);
+ Decision.IfEq (dtree.Location, p, con, assign, if_false);
| Decision.Success
- | Decision.Assign => Decision.Assign (path, decl, dtree)
+ | Decision.Assign => Decision.Assign (dtree.Location, path, decl, dtree)
| Decision.Failure => dtree
}
Modified: nemerle/trunk/ncc/typing/Typer2.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer2.n (original)
+++ nemerle/trunk/ncc/typing/Typer2.n Sun Dec 17 22:11:31 2006
@@ -642,7 +642,7 @@
match (kind) {
| ConversionKind.MethodCall (sr) =>
MarkAsUsed (sr.mem, expr.Location);
- TExpr.Call (target, sr, [Parm (expr)], false)
+ TExpr.Call (expr.Location, target, sr, [Parm (expr)], false)
| ConversionKind.DownCast =>
if (expr.Type.TryRequire (target)) {
expr.Type.ForceRequire (target);
@@ -650,15 +650,15 @@
Message.HintOnce (10001, "consider using : instead of :>");
BuildEnforcement (expr, target)
} else
- TExpr.TypeConversion (target, expr, target, kind)
+ TExpr.TypeConversion (expr.Location, target, expr, target, kind)
| ConversionKind.Unspecified =>
if (expr.Type.TryRequire (target)) {
expr.Type.ForceRequire (target);
BuildEnforcement (expr, target)
} else
- TExpr.TypeConversion (target, expr, target, ConversionKind.DownCast ())
+ TExpr.TypeConversion (expr.Location, target, expr, target, ConversionKind.DownCast ())
| _ =>
- TExpr.TypeConversion (target, expr, target, kind)
+ TExpr.TypeConversion (expr.Location, target, expr, target, kind)
}
}
More information about the svn
mailing list