about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-02-09 17:09:50 +0000
committerbors <bors@rust-lang.org>2017-02-09 17:09:50 +0000
commit405327635419e22a956dfe8f7caf4817c8ae5e93 (patch)
treeff15270c6e603dc05e997510737a9c8ac488cc6c
parente7fc53b8f0595d9b5be6a3b64d29d3cfed7c7199 (diff)
parentb037c5211b9ba496252af5a0369b48649f91ccc8 (diff)
downloadrust-405327635419e22a956dfe8f7caf4817c8ae5e93.tar.gz
rust-405327635419e22a956dfe8f7caf4817c8ae5e93.zip
Auto merge of #38109 - tromey:main-subprogram, r=michaelwoerister
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
-rw-r--r--src/librustc_llvm/ffi.rs1
-rw-r--r--src/librustc_trans/debuginfo/mod.rs12
-rw-r--r--src/rustllvm/RustWrapper.cpp6
-rw-r--r--src/test/codegen/mainsubprogram.rs26
-rw-r--r--src/test/codegen/mainsubprogramstart.rs30
5 files changed, 74 insertions, 1 deletions
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 949e949f673..5273910d1d9 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -468,6 +468,7 @@ pub mod debuginfo {
             const FlagStaticMember        = (1 << 12),
             const FlagLValueReference     = (1 << 13),
             const FlagRValueReference     = (1 << 14),
+            const FlagMainSubprogram      = (1 << 21),
         }
     }
 }
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index 729eae15ad6..e9b592ec8fd 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -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,
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index f3b52b71b99..27233a8b075 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -352,6 +352,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!
 };
@@ -438,6 +439,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;
 }
diff --git a/src/test/codegen/mainsubprogram.rs b/src/test/codegen/mainsubprogram.rs
new file mode 100644
index 00000000000..657f4b662f7
--- /dev/null
+++ b/src/test/codegen/mainsubprogram.rs
@@ -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() {
+}
diff --git a/src/test/codegen/mainsubprogramstart.rs b/src/test/codegen/mainsubprogramstart.rs
new file mode 100644
index 00000000000..cd34a1670dc
--- /dev/null
+++ b/src/test/codegen/mainsubprogramstart.rs
@@ -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;
+}