Open
Description
It seems that Rust debuginfo always writes decl_line
of 1 for formal parameters.
With this line.rs
:
#![crate_type = "dylib"] // line 1
pub fn foo( // 2
x: i32, // 3
y: i32) // 4
-> i32 // 5
{ x + y } // 6
With:
$ rustc +nightly -Vv
rustc 1.22.0-nightly (185cc5f26 2017-10-02)
binary: rustc
commit-hash: 185cc5f26d2c8a794189b028b43f6a3b8fc586db
commit-date: 2017-10-02
host: x86_64-unknown-linux-gnu
release: 1.22.0-nightly
LLVM version: 4.0
I get this output:
$ rustc +nightly -g line.rs
$ dwgrep 'entry ?(@AT_name == "foo") child*' libline.so
[2f] subprogram
low_pc 0x42100
high_pc 66
frame_base 0..0xffffffffffffffff:0 reg6
linkage_name "_ZN4line3fooE"
name "foo"
decl_file "/tmp/line.rs"
decl_line 2
type [8c] base_type
external true
[4c] formal_parameter
location 0..0xffffffffffffffff:0 fbreg <-16>
name "x"
decl_file "/tmp/line.rs"
decl_line 1
type [8c] base_type
[5a] formal_parameter
location 0..0xffffffffffffffff:0 fbreg <-12>
name "y"
decl_file "/tmp/line.rs"
decl_line 1
type [8c] base_type
[68] lexical_block
ranges 0x4210e..0x4212a, 0x4213a..0x42142
[6d] variable
location 0..0xffffffffffffffff:0 fbreg <-8>
name "x"
decl_file "/tmp/line.rs"
decl_line 3
type [8c] base_type
[7b] variable
location 0..0xffffffffffffffff:0 fbreg <-4>
name "y"
decl_file "/tmp/line.rs"
decl_line 4
type [8c] base_type
So it describes the formal parameters of x
and y
both with line 1, but also describes local variables with the correct lines 3 and 4.
In LLVM IR it looks like this, with the wrong lines in !10
and !13
:
$ rustc +nightly -g line.rs --emit=llvm-ir
$ sed -n '/DIComp/,$p' line.ll
!0 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !1, producer: "clang LLVM (rustc version 1.22.0-nightly (185cc5f26 2017-10-02))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "line.rs", directory: "/tmp")
!2 = !{}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = distinct !DISubprogram(name: "foo", linkageName: "_ZN4line3fooE", scope: !5, file: !1, line: 2, type: !7, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, templateParams: !2, variables: !2)
!5 = !DINamespace(name: "line", scope: null, file: !6)
!6 = !DIFile(filename: "<unknown>", directory: "")
!7 = !DISubroutineType(types: !8)
!8 = !{!9, !9, !9}
!9 = !DIBasicType(name: "i32", size: 32, encoding: DW_ATE_signed)
!10 = !DILocalVariable(name: "x", arg: 1, scope: !4, file: !1, line: 1, type: !9)
!11 = !DIExpression()
!12 = !DILocation(line: 1, scope: !4)
!13 = !DILocalVariable(name: "y", arg: 2, scope: !4, file: !1, line: 1, type: !9)
!14 = !DILocalVariable(name: "x", scope: !15, file: !1, line: 3, type: !9, align: 4)
!15 = distinct !DILexicalBlock(scope: !4, file: !1, line: 6)
!16 = !DILocation(line: 3, scope: !15)
!17 = !DILocalVariable(name: "y", scope: !15, file: !1, line: 4, type: !9, align: 4)
!18 = !DILocation(line: 4, scope: !15)
!19 = !DILocation(line: 6, scope: !15)
!20 = !DILocation(line: 6, scope: !4)