Emit DW_AT_main_subprogram

This changes rustc to emit DW_AT_main_subprogram on the "main" program.
This lets gdb suitably stop at the user's main in response to
"start" (rather than the library's main, which is what happens
currently).

Fixes #32620
r? michaelwoerister
This commit is contained in:
Tom Tromey 2016-11-30 14:59:45 -07:00
parent d7777ae682
commit b037c5211b
5 changed files with 74 additions and 1 deletions

View File

@ -459,6 +459,7 @@ pub mod debuginfo {
const FlagStaticMember = (1 << 12),
const FlagLValueReference = (1 << 13),
const FlagRValueReference = (1 << 14),
const FlagMainSubprogram = (1 << 21),
}
}
}

View File

@ -257,6 +257,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let function_name = CString::new(name).unwrap();
let linkage_name = CString::new(linkage_name).unwrap();
let mut flags = DIFlags::FlagPrototyped;
match *cx.sess().entry_fn.borrow() {
Some((id, _)) => {
if local_id == Some(id) {
flags = flags | DIFlags::FlagMainSubprogram;
}
}
None => {}
};
let fn_metadata = unsafe {
llvm::LLVMRustDIBuilderCreateFunction(
DIB(cx),
@ -269,7 +279,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
is_local_to_unit,
true,
scope_line as c_uint,
DIFlags::FlagPrototyped,
flags,
cx.sess().opts.optimize != config::OptLevel::No,
llfn,
template_parameters,

View File

@ -346,6 +346,7 @@ enum class LLVMRustDIFlags : uint32_t {
FlagStaticMember = (1 << 12),
FlagLValueReference = (1 << 13),
FlagRValueReference = (1 << 14),
FlagMainSubprogram = (1 << 21),
// Do not add values that are not supported by the minimum LLVM
// version we support!
};
@ -432,6 +433,11 @@ static unsigned fromRust(LLVMRustDIFlags Flags) {
if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
Result |= DINode::DIFlags::FlagRValueReference;
}
#if LLVM_RUSTLLVM || LLVM_VERSION_GE(4, 0)
if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) {
Result |= DINode::DIFlags::FlagMainSubprogram;
}
#endif
return Result;
}

View File

@ -0,0 +1,26 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// The minimum LLVM version is set to 3.8, but really this test
// depends on a patch that is was committed to upstream LLVM before
// 4.0; and also backported to the Rust LLVM fork.
// ignore-tidy-linelength
// ignore-windows
// ignore-macos
// min-llvm-version 3.8
// compile-flags: -g -C no-prepopulate-passes
// CHECK-LABEL: @main
// CHECK: {{.*}}DISubprogram{{.*}}name: "main",{{.*}}DIFlagMainSubprogram{{.*}}
pub fn main() {
}

View File

@ -0,0 +1,30 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// The minimum LLVM version is set to 3.8, but really this test
// depends on a patch that is was committed to upstream LLVM before
// 4.0; and also backported to the Rust LLVM fork.
// ignore-tidy-linelength
// ignore-windows
// ignore-macos
// min-llvm-version 3.8
// compile-flags: -g -C no-prepopulate-passes
#![feature(start)]
// CHECK-LABEL: @main
// CHECK: {{.*}}DISubprogram{{.*}}name: "start",{{.*}}DIFlagMainSubprogram{{.*}}
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
return 0;
}