[m-rev.] diff: track line numbers in generated erlang source files

Peter Wang wangp at students.csse.unimelb.edu.au
Wed Aug 1 15:53:17 AEST 2007


Estimated hours taken: 1.5
Branches: main

Output -file(FILE, LINE). directives in generated Erlang source files to tell
the Erlang compiler where those lines of code originated from.  We currently
only do it around foreign code because it is relatively easy and most useful.

compiler/elds.m:
compiler/erl_call_gen.m:
	Remember where code for a foreign_proc came from.

compiler/elds_to_erlang.m:
	Output -file directives for pragma foreign_decl, foreign_code and
	before the definitions of functions for foreign_procs.
	We don't handle foreign_procs which are inlined into other functions
	because -file directives cannot appear in the middle of a function
	definition, only at the top level.

compiler/erl_code_util.m:
	Conform to the change in the ELDS.


Index: compiler/elds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/elds.m,v
retrieving revision 1.16
diff -u -r1.16 elds.m
--- compiler/elds.m	20 Jul 2007 05:11:16 -0000	1.16
+++ compiler/elds.m	1 Aug 2007 05:35:28 -0000
@@ -196,7 +196,7 @@
     ;       elds_throw(elds_expr)
 
             % A piece of code to be embedded directly in the generated code.
-    ;       elds_foreign_code(string)
+    ;       elds_foreign_code(string, prog_context)
 
             % ExprA ! ExprB
             %
Index: compiler/elds_to_erlang.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/elds_to_erlang.m,v
retrieving revision 1.25
diff -u -r1.25 elds_to_erlang.m
--- compiler/elds_to_erlang.m	20 Jul 2007 05:11:16 -0000	1.25
+++ compiler/elds_to_erlang.m	1 Aug 2007 05:35:28 -0000
@@ -366,8 +366,7 @@
 
 :- func elds_get_env_var_names_from_defn(elds_defn) = set(string).
 
-elds_get_env_var_names_from_defn(ProcDefn) = EnvVarNameSet :-
-    ProcDefn = elds_defn(_, _, _, EnvVarNameSet).
+elds_get_env_var_names_from_defn(ProcDefn) = ProcDefn ^ defn_env_vars.
 
 :- pred output_env_var_directive(string::in, io::di, io::uo) is det.
 
@@ -390,16 +389,36 @@
 
 :- pred output_foreign_decl_code(foreign_decl_code::in, io::di, io::uo) is det.
 
-output_foreign_decl_code(foreign_decl_code(_Lang, _IsLocal, Code, _Context),
+output_foreign_decl_code(foreign_decl_code(_Lang, _IsLocal, Code, Context),
         !IO) :-
+    output_file_directive(Context, !IO),
     io.write_string(Code, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    reset_file_directive(!IO).
 
 :- pred output_foreign_body_code(foreign_body_code::in, io::di, io::uo) is det.
 
-output_foreign_body_code(foreign_body_code(_Lang, Code, _Context), !IO) :-
+output_foreign_body_code(foreign_body_code(_Lang, Code, Context), !IO) :-
+    output_file_directive(Context, !IO),
     io.write_string(Code, !IO),
-    io.nl(!IO).
+    io.nl(!IO),
+    reset_file_directive(!IO).
+
+:- pred output_file_directive(context::in, io::di, io::uo) is det.
+
+output_file_directive(context(FileName, LineNr), !IO) :-
+    io.write_string("-file(""", !IO),
+    write_with_escaping(in_string, FileName, !IO),
+    io.write_string(""", ", !IO),
+    io.write_int(LineNr, !IO),
+    io.write_string(").\n", !IO).
+
+:- pred reset_file_directive(io::di, io::uo) is det.
+
+reset_file_directive(!IO) :-
+    io.output_stream_name(FileName, !IO),
+    io.get_output_file_number(LineNr, !IO),
+    output_file_directive(context(FileName, LineNr), !IO).
 
 %-----------------------------------------------------------------------------%
 
@@ -434,8 +453,30 @@
     (
         Body = body_defined_here(Clause),
         io.nl(!IO),
-        output_pred_proc_id(ModuleInfo, PredProcId, !IO),
-        output_toplevel_clause(ModuleInfo, VarSet, Clause, !IO)
+        (
+            % If the function definition is for a pragma foreign_proc then
+            % output -file(File, Line). before and after the function
+            % definition.
+            Clause = elds_clause(_HeadVars, ClauseBody),
+            ClauseBody = elds_call(elds_call_ho(Fun), _CallArgs),
+            Fun = elds_fun(elds_clause(_FunVars, FunBody)),
+            FunBody = elds_block([
+                elds_foreign_code(_Code, Context),
+                _PlaceOutputs
+            ])
+        ->
+            % We need to subtract 3 lines so that the line numbers in the
+            % foreign code block will match up with the line numbers in the
+            % source file.
+            Context = context(FileName, LineNr),
+            output_file_directive(context(FileName, LineNr - 3), !IO),
+            output_pred_proc_id(ModuleInfo, PredProcId, !IO),
+            output_toplevel_clause(ModuleInfo, VarSet, Clause, !IO),
+            reset_file_directive(!IO)
+        ;
+            output_pred_proc_id(ModuleInfo, PredProcId, !IO),
+            output_toplevel_clause(ModuleInfo, VarSet, Clause, !IO)
+        )
     ;
         Body = body_external(_Arity)
     ).
@@ -643,8 +684,7 @@
             io.write_string("()", !IO)
         )
     ;
-        Expr = elds_foreign_code(Code),
-        nl(!IO),
+        Expr = elds_foreign_code(Code, _Context),
         io.write_string(Code, !IO),
         nl_indent_line(Indent, !IO)
     ;
Index: compiler/erl_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_call_gen.m,v
retrieving revision 1.10
diff -u -r1.10 erl_call_gen.m
--- compiler/erl_call_gen.m	20 Jul 2007 07:06:46 -0000	1.10
+++ compiler/erl_call_gen.m	1 Aug 2007 05:35:28 -0000
@@ -596,7 +596,7 @@
     elds_expr::out, erl_gen_info::in, erl_gen_info::out) is det.
 
 erl_gen_ordinary_pragma_foreign_code(ForeignArgs, ForeignCode,
-        CodeModel, _OuterContext, MaybeSuccessExpr, Statement, !Info) :-
+        CodeModel, OuterContext, MaybeSuccessExpr, Statement, !Info) :-
     %
     % In the following, F<n> are input variables to the foreign code (with
     % fixed names), and G<n> are output variables from the foreign code
@@ -641,7 +641,7 @@
     InputVarsNames = list.map(foreign_arg_name, InputForeignArgs),
     OutputVarsNames = list.map(foreign_arg_name, OutputForeignArgs),
 
-    ForeignCodeExpr = elds_foreign_code(ForeignCode),
+    ForeignCodeExpr = elds_foreign_code(ForeignCode, OuterContext),
 
     % Create the inner lambda function.
     (
Index: compiler/erl_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_code_util.m,v
retrieving revision 1.10
diff -u -r1.10 erl_code_util.m
--- compiler/erl_code_util.m	20 Jul 2007 07:06:47 -0000	1.10
+++ compiler/erl_code_util.m	1 Aug 2007 05:35:28 -0000
@@ -522,7 +522,7 @@
         Expr = elds_receive(Cases)
     ;
         ( Expr0 = elds_rtti_ref(_)
-        ; Expr0 = elds_foreign_code(_)
+        ; Expr0 = elds_foreign_code(_, _)
         ),
         Expr = Expr0
     ).
@@ -686,7 +686,7 @@
         erl_vars_in_cases(Cases, !Set)
     ;
         ( Expr = elds_rtti_ref(_)
-        ; Expr = elds_foreign_code(_)
+        ; Expr = elds_foreign_code(_, _)
         )
     ).
 
@@ -825,7 +825,7 @@
         Expr = elds_rtti_ref(_),
         Size = 1
     ;
-        Expr = elds_foreign_code(_),
+        Expr = elds_foreign_code(_, _),
         % Arbitrary number.
         Size = 10000
     ).
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list