[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