Skip to content

Commit 3eb3a02

Browse files
committed
auto merge of #13143 : gentlefolk/rust/issue-9227, r=michaelwoerister
Only supports crate level statics. No debug info is generated for function level statics. Closes #9227. As discussed at the end of the comments for #9227, I took an initial stab at adding support for function level statics and decided it would be enough work to warrant being split into a separate issue. See #13144 for the new issue describing the need to add support for function level static variables.
2 parents 363198b + f4518cd commit 3eb3a02

15 files changed

+711
-77
lines changed

src/librustc/lib/llvm.rs

+13
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ pub mod debuginfo {
277277
pub type DIDerivedType = DIType;
278278
pub type DICompositeType = DIDerivedType;
279279
pub type DIVariable = DIDescriptor;
280+
pub type DIGlobalVariable = DIDescriptor;
280281
pub type DIArray = DIDescriptor;
281282
pub type DISubrange = DIDescriptor;
282283

@@ -1589,6 +1590,18 @@ pub mod llvm {
15891590
Col: c_uint)
15901591
-> DILexicalBlock;
15911592

1593+
pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
1594+
Context: DIDescriptor,
1595+
Name: *c_char,
1596+
LinkageName: *c_char,
1597+
File: DIFile,
1598+
LineNo: c_uint,
1599+
Ty: DIType,
1600+
isLocalToUnit: bool,
1601+
Val: ValueRef,
1602+
Decl: ValueRef)
1603+
-> DIGlobalVariable;
1604+
15921605
pub fn LLVMDIBuilderCreateLocalVariable(Builder: DIBuilderRef,
15931606
Tag: c_uint,
15941607
Scope: DIDescriptor,

src/librustc/middle/trans/consts.rs

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use middle::trans::inline;
2828
use middle::trans::machine;
2929
use middle::trans::type_::Type;
3030
use middle::trans::type_of;
31+
use middle::trans::debuginfo;
3132
use middle::ty;
3233
use util::ppaux::{Repr, ty_to_str};
3334

@@ -688,5 +689,6 @@ pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
688689
if m != ast::MutMutable {
689690
llvm::LLVMSetGlobalConstant(g, True);
690691
}
692+
debuginfo::create_global_var_metadata(ccx, id, g);
691693
}
692694
}

src/librustc/middle/trans/debuginfo.rs

+72-7
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,66 @@ pub fn finalize(cx: &CrateContext) {
280280
};
281281
}
282282

283+
/// Creates debug information for the given global variable.
284+
///
285+
/// Adds the created metadata nodes directly to the crate's IR.
286+
pub fn create_global_var_metadata(cx: &CrateContext,
287+
node_id: ast::NodeId,
288+
global: ValueRef) {
289+
if cx.dbg_cx.is_none() {
290+
return;
291+
}
292+
293+
let var_item = cx.tcx.map.get(node_id);
294+
295+
let (ident, span) = match var_item {
296+
ast_map::NodeItem(item) => {
297+
match item.node {
298+
ast::ItemStatic(..) => (item.ident, item.span),
299+
_ => cx.sess().span_bug(item.span,
300+
format!("debuginfo::create_global_var_metadata() -
301+
Captured var-id refers to unexpected ast_item
302+
variant: {:?}",
303+
var_item))
304+
}
305+
},
306+
_ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() - Captured var-id \
307+
refers to unexpected ast_map variant: {:?}",
308+
var_item))
309+
};
310+
311+
let filename = span_start(cx, span).file.name.clone();
312+
let file_metadata = file_metadata(cx, filename);
313+
314+
let is_local_to_unit = is_node_local_to_unit(cx, node_id);
315+
let loc = span_start(cx, span);
316+
317+
let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
318+
let type_metadata = type_metadata(cx, variable_type, span);
319+
320+
let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
321+
let var_name = token::get_ident(ident).get().to_str();
322+
let linkage_name = namespace_node.mangled_name_of_contained_item(var_name);
323+
let var_scope = namespace_node.scope;
324+
325+
var_name.with_c_str(|var_name| {
326+
linkage_name.with_c_str(|linkage_name| {
327+
unsafe {
328+
llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
329+
var_scope,
330+
var_name,
331+
linkage_name,
332+
file_metadata,
333+
loc.line as c_uint,
334+
type_metadata,
335+
is_local_to_unit,
336+
global,
337+
ptr::null());
338+
}
339+
})
340+
});
341+
}
342+
283343
/// Creates debug information for the given local variable.
284344
///
285345
/// Adds the created metadata nodes directly to the crate's IR.
@@ -640,13 +700,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
640700
// Clang sets this parameter to the opening brace of the function's block, so let's do this too.
641701
let scope_line = span_start(cx, top_level_block.span).line;
642702

643-
// The is_local_to_unit flag indicates whether a function is local to the current compilation
644-
// unit (i.e. if it is *static* in the C-sense). The *reachable* set should provide a good
645-
// approximation of this, as it contains everything that might leak out of the current crate
646-
// (by being externally visible or by being inlined into something externally visible). It might
647-
// better to use the `exported_items` set from `driver::CrateAnalysis` in the future, but (atm)
648-
// this set is not available in the translation pass.
649-
let is_local_to_unit = !cx.reachable.contains(&fn_ast_id);
703+
let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
650704

651705
let fn_metadata = function_name.with_c_str(|function_name| {
652706
linkage_name.with_c_str(|linkage_name| {
@@ -854,6 +908,17 @@ pub fn create_function_debug_context(cx: &CrateContext,
854908
// Module-Internal debug info creation functions
855909
//=-------------------------------------------------------------------------------------------------
856910

911+
fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
912+
{
913+
// The is_local_to_unit flag indicates whether a function is local to the current compilation
914+
// unit (i.e. if it is *static* in the C-sense). The *reachable* set should provide a good
915+
// approximation of this, as it contains everything that might leak out of the current crate
916+
// (by being externally visible or by being inlined into something externally visible). It might
917+
// better to use the `exported_items` set from `driver::CrateAnalysis` in the future, but (atm)
918+
// this set is not available in the translation pass.
919+
!cx.reachable.contains(&node_id)
920+
}
921+
857922
fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
858923
return unsafe {
859924
llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)

src/rustllvm/RustWrapper.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,28 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
323323
unwrapDI<DIFile>(File), Line, Col));
324324
}
325325

326+
extern "C" LLVMValueRef LLVMDIBuilderCreateStaticVariable(
327+
DIBuilderRef Builder,
328+
LLVMValueRef Context,
329+
const char* Name,
330+
const char* LinkageName,
331+
LLVMValueRef File,
332+
unsigned LineNo,
333+
LLVMValueRef Ty,
334+
bool isLocalToUnit,
335+
LLVMValueRef Val,
336+
LLVMValueRef Decl = NULL) {
337+
return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
338+
Name,
339+
LinkageName,
340+
unwrapDI<DIFile>(File),
341+
LineNo,
342+
unwrapDI<DIType>(Ty),
343+
isLocalToUnit,
344+
unwrap(Val),
345+
unwrapDI<MDNode*>(Decl)));
346+
}
347+
326348
extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
327349
DIBuilderRef Builder,
328350
unsigned Tag,

src/rustllvm/rustllvm.def.in

+1
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ LLVMDIBuilderCreate
586586
LLVMDIBuilderDispose
587587
LLVMDIBuilderFinalize
588588
LLVMDIBuilderCreateCompileUnit
589+
LLVMDIBuilderCreateStaticVariable
589590
LLVMDIBuilderCreateLocalVariable
590591
LLVMDIBuilderCreateFunction
591592
LLVMDIBuilderCreateFile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ignore-android: FIXME(#10381)
12+
13+
// compile-flags:-g
14+
// debugger:rbreak zzz
15+
// debugger:run
16+
// debugger:finish
17+
// debugger:whatis 'basic-types-globals-metadata::B'
18+
// check:type = bool
19+
// debugger:whatis 'basic-types-globals-metadata::I'
20+
// check:type = int
21+
// debugger:whatis 'basic-types-globals-metadata::C'
22+
// check:type = char
23+
// debugger:whatis 'basic-types-globals-metadata::I8'
24+
// check:type = i8
25+
// debugger:whatis 'basic-types-globals-metadata::I16'
26+
// check:type = i16
27+
// debugger:whatis 'basic-types-globals-metadata::I32'
28+
// check:type = i32
29+
// debugger:whatis 'basic-types-globals-metadata::I64'
30+
// check:type = i64
31+
// debugger:whatis 'basic-types-globals-metadata::U'
32+
// check:type = uint
33+
// debugger:whatis 'basic-types-globals-metadata::U8'
34+
// check:type = u8
35+
// debugger:whatis 'basic-types-globals-metadata::U16'
36+
// check:type = u16
37+
// debugger:whatis 'basic-types-globals-metadata::U32'
38+
// check:type = u32
39+
// debugger:whatis 'basic-types-globals-metadata::U64'
40+
// check:type = u64
41+
// debugger:whatis 'basic-types-globals-metadata::F32'
42+
// check:type = f32
43+
// debugger:whatis 'basic-types-globals-metadata::F64'
44+
// check:type = f64
45+
// debugger:continue
46+
47+
#[allow(unused_variable)];
48+
49+
static B: bool = false;
50+
static I: int = -1;
51+
static C: char = 'a';
52+
static I8: i8 = 68;
53+
static I16: i16 = -16;
54+
static I32: i32 = -32;
55+
static I64: i64 = -64;
56+
static U: uint = 1;
57+
static U8: u8 = 100;
58+
static U16: u16 = 16;
59+
static U32: u32 = 32;
60+
static U64: u64 = 64;
61+
static F32: f32 = 2.5;
62+
static F64: f64 = 3.5;
63+
64+
fn main() {
65+
_zzz();
66+
}
67+
68+
fn _zzz() {()}
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
12+
// as its numerical value along with its associated ASCII char, there
13+
// doesn't seem to be any way around this. Also, gdb doesn't know
14+
// about UTF-32 character encoding and will print a rust char as only
15+
// its numerical value.
16+
17+
// ignore-android: FIXME(#10381)
18+
19+
// compile-flags:-g
20+
// debugger:rbreak zzz
21+
// debugger:run
22+
// debugger:finish
23+
// debugger:print 'basic-types-globals::B'
24+
// check:$1 = false
25+
// debugger:print 'basic-types-globals::I'
26+
// check:$2 = -1
27+
// debugger:print 'basic-types-globals::C'
28+
// check:$3 = 97
29+
// debugger:print/d 'basic-types-globals::I8'
30+
// check:$4 = 68
31+
// debugger:print 'basic-types-globals::I16'
32+
// check:$5 = -16
33+
// debugger:print 'basic-types-globals::I32'
34+
// check:$6 = -32
35+
// debugger:print 'basic-types-globals::I64'
36+
// check:$7 = -64
37+
// debugger:print 'basic-types-globals::U'
38+
// check:$8 = 1
39+
// debugger:print/d 'basic-types-globals::U8'
40+
// check:$9 = 100
41+
// debugger:print 'basic-types-globals::U16'
42+
// check:$10 = 16
43+
// debugger:print 'basic-types-globals::U32'
44+
// check:$11 = 32
45+
// debugger:print 'basic-types-globals::U64'
46+
// check:$12 = 64
47+
// debugger:print 'basic-types-globals::F32'
48+
// check:$13 = 2.5
49+
// debugger:print 'basic-types-globals::F64'
50+
// check:$14 = 3.5
51+
// debugger:continue
52+
53+
#[allow(unused_variable)];
54+
55+
static B: bool = false;
56+
static I: int = -1;
57+
static C: char = 'a';
58+
static I8: i8 = 68;
59+
static I16: i16 = -16;
60+
static I32: i32 = -32;
61+
static I64: i64 = -64;
62+
static U: uint = 1;
63+
static U8: u8 = 100;
64+
static U16: u16 = 16;
65+
static U32: u32 = 32;
66+
static U64: u64 = 64;
67+
static F32: f32 = 2.5;
68+
static F64: f64 = 3.5;
69+
70+
fn main() {
71+
_zzz();
72+
}
73+
74+
fn _zzz() {()}

src/test/debug-info/basic-types-metadata.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@
4646
// check:type = f64
4747
// debugger:info functions _yyy
4848
// check:[...]![...]_yyy([...])([...]);
49-
// debugger:detach
50-
// debugger:quit
49+
// debugger:continue
5150

5251
#[allow(unused_variable)];
5352

0 commit comments

Comments
 (0)