Skip to content

Commit f984cda

Browse files
jyasskingraydon
authored andcommitted
---
yaml --- r: 305 b: refs/heads/master c: ca95da8 h: refs/heads/master i: 303: 373453c v: v3
1 parent c551074 commit f984cda

File tree

2 files changed

+88
-28
lines changed

2 files changed

+88
-28
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: d974aade934d7bca50fe66eb1de849d4b666828b
2+
refs/heads/master: ca95da8bea639bbc99dfd160db0e58a552c9fa26

trunk/src/boot/llvm/lltrans.ml

Lines changed: 87 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ let trans_crate
2424
in
2525

2626
(* Helpers for adding metadata. *)
27-
let (dbg_mdkind:int) = Llvm.mdkind_id llctx "dbg" in
28-
let set_dbg_metadata (inst:Llvm.llvalue) (md:Llvm.llvalue) : unit =
29-
Llvm.set_metadata inst dbg_mdkind md
30-
in
3127
let md_str (s:string) : Llvm.llvalue = Llvm.mdstring llctx s in
3228
let md_node (vals:Llvm.llvalue array) : Llvm.llvalue =
3329
Llvm.mdnode llctx vals
@@ -43,6 +39,73 @@ let trans_crate
4339
const_i32 (llvm_debug_version lor (Dwarf.dw_tag_to_int tag))
4440
in
4541

42+
(* See http://llvm.org/docs/SourceLevelDebugging.html. *)
43+
let crate_compile_unit : Llvm.llvalue =
44+
let name = Hashtbl.find sem_cx.Semant.ctxt_item_files crate.id in
45+
md_node [| const_dw_tag Dwarf.DW_TAG_compile_unit;
46+
const_i32 0; (* Unused. *)
47+
const_i32 2; (* DW_LANG_C. FIXME: Pick a Rust DW_LANG code. *)
48+
md_str (Filename.basename name);
49+
md_str (Filename.concat
50+
(Sys.getcwd()) (Filename.dirname name));
51+
md_str ("Rustboot " ^ Version.version);
52+
(* This is the main compile unit. There must be exactly one of
53+
these in an LLVM module for it to emit debug info. *)
54+
const_i1 1;
55+
(* There are a couple more supported fields, which we ignore
56+
here. *)
57+
|]
58+
in
59+
let di_file (filepath:string) =
60+
md_node [| const_dw_tag Dwarf.DW_TAG_file_type;
61+
md_str (Filename.basename filepath);
62+
md_str (Filename.concat
63+
(Sys.getcwd()) (Filename.dirname filepath));
64+
crate_compile_unit
65+
|]
66+
in
67+
let di_subprogram (scope:Llvm.llvalue) (name:string) (fullname:string)
68+
(di_file:Llvm.llvalue) (line:int) (llfunction:Llvm.llvalue)
69+
: Llvm.llvalue =
70+
(* 'scope' is generally a compile unit or other subprogram. *)
71+
md_node [| const_dw_tag Dwarf.DW_TAG_subprogram;
72+
const_i32 0; (* Unused. *)
73+
scope;
74+
md_str name;
75+
md_str fullname; (* Display name *)
76+
md_str fullname; (* Linkage name *)
77+
di_file;
78+
const_i32 line;
79+
(* FIXME: Fill in the following fields. *)
80+
md_node [||];
81+
const_i1 1;
82+
const_i1 1;
83+
const_i32 0;
84+
const_i32 0;
85+
md_node [||];
86+
const_i1 0;
87+
const_i1 0;
88+
llfunction (* The llvm::Function this reflects. *)
89+
|]
90+
in
91+
let di_location (line:int) (col:int) (scope:Llvm.llvalue) : Llvm.llvalue =
92+
(* 'scope' is generally a subprogram or block. *)
93+
md_node [| const_i32 line; const_i32 col; scope; const_i32 0 |]
94+
in
95+
96+
(* Sets the 'llbuilder's current location (which it attaches to all
97+
instructions) to the location of the start of the 'id' node within
98+
'scope', usually a subprogram or lexical block. *)
99+
let set_debug_location
100+
(llbuilder:Llvm.llbuilder) (scope:Llvm.llvalue) (id:node_id)
101+
: unit =
102+
match Session.get_span sess id with
103+
None -> ()
104+
| Some {lo=(_, line, col)} ->
105+
Llvm.set_current_debug_location llbuilder
106+
(di_location line col scope)
107+
in
108+
46109
(* Translation of our node_ids into LLVM identifiers, which are strings. *)
47110
let next_anon_llid = ref 0 in
48111
let num_llid num klass = Printf.sprintf "%s%d" klass num in
@@ -475,44 +538,31 @@ let trans_crate
475538
in
476539

477540
let (llitems:(node_id, Llvm.llvalue) Hashtbl.t) = Hashtbl.create 0 in
541+
(* Maps a fn's or block's id to an LLVM metadata node (subprogram or
542+
lexical block) representing it. *)
543+
let (dbg_llscopes:(node_id, Llvm.llvalue) Hashtbl.t) = Hashtbl.create 0 in
478544
let declare_mod_item
479545
(name:Ast.ident)
480546
{ node = { Ast.decl_item = (item:Ast.mod_item') }; id = id }
481547
: unit =
482548
let full_name = Semant.item_str sem_cx id in
483-
let line_num =
549+
let (filename, line_num) =
484550
match Session.get_span sess id with
485-
None -> 0
551+
None -> ("", 0)
486552
| Some span ->
487-
let (_, line, _) = span.lo in
488-
line
553+
let (file, line, _) = span.lo in
554+
(file, line)
489555
in
490556
match item with
491557
Ast.MOD_ITEM_fn _ ->
492558
let llty = trans_ty (ty_of_item id) in
493559
let llfn = Llvm.declare_function ("_rust_" ^ name) llty llmod in
494-
let meta =
495-
md_node
496-
[|
497-
const_dw_tag Dwarf.DW_TAG_subprogram;
498-
const_i32 0; (* unused *)
499-
const_i32 0; (* context metadata llvalue *)
500-
md_str name;
501-
md_str full_name;
502-
md_str full_name;
503-
const_i32 0; (* file metadata llvalue *)
504-
const_i32 line_num;
505-
const_i32 0; (* type descriptor metadata llvalue *)
506-
const_i1 1; (* flag: local to compile unit? *)
507-
const_i1 1; (* flag: defined in compile unit? *)
508-
|]
560+
let meta = (di_subprogram crate_compile_unit name full_name
561+
(di_file filename) line_num llfn)
509562
in
510563
Llvm.set_function_call_conv Llvm.CallConv.c llfn;
511564
Hashtbl.add llitems id llfn;
512-
513-
(* FIXME: Adding metadata does not work yet. . *)
514-
let _ = fun _ -> set_dbg_metadata llfn meta in
515-
()
565+
Hashtbl.add dbg_llscopes id meta
516566

517567
| _ -> () (* TODO *)
518568
in
@@ -527,6 +577,7 @@ let trans_crate
527577
let llfn = Hashtbl.find llitems fn_id in
528578
let lloutptr = Llvm.param llfn 0 in
529579
let lltask = Llvm.param llfn 1 in
580+
let llsubprogram = Hashtbl.find dbg_llscopes fn_id in
530581

531582
(* LLVM requires that functions be grouped into basic blocks terminated by
532583
* terminator instructions, while our AST is less strict. So we have to do
@@ -621,6 +672,12 @@ let trans_crate
621672
(stmts:Ast.stmt list)
622673
(terminate:(Llvm.llbuilder -> node_id -> unit))
623674
: unit =
675+
let set_debug_loc (id:node_id) =
676+
(* Sets the llbuilder's current location (which it attaches to all
677+
instructions) to the location of the start of the 'id' node. *)
678+
set_debug_location llbuilder llsubprogram id
679+
in
680+
624681
let trans_literal
625682
(lit:Ast.lit)
626683
: Llvm.llvalue =
@@ -645,6 +702,7 @@ let trans_crate
645702
iflog (fun _ -> log sem_cx "trans_lval: %a" Ast.sprintf_lval lval);
646703
match lval with
647704
Ast.LVAL_base { id = base_id } ->
705+
set_debug_loc base_id;
648706
let id =
649707
Hashtbl.find sem_cx.Semant.ctxt_lval_to_referent base_id
650708
in
@@ -760,6 +818,8 @@ let trans_crate
760818
in
761819
let trans_tail () = trans_tail_with_builder llbuilder in
762820

821+
set_debug_loc head.id;
822+
763823
match head.node with
764824
Ast.STMT_init_tup (dest, elems) ->
765825
let zero = const_i32 0 in

0 commit comments

Comments
 (0)