Skip to content

Commit

Permalink
auto merge of #13143 : gentlefolk/rust/issue-9227, r=michaelwoerister
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Mar 29, 2014
2 parents 363198b + f4518cd commit 3eb3a02
Show file tree
Hide file tree
Showing 15 changed files with 711 additions and 77 deletions.
13 changes: 13 additions & 0 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ pub mod debuginfo {
pub type DIDerivedType = DIType;
pub type DICompositeType = DIDerivedType;
pub type DIVariable = DIDescriptor;
pub type DIGlobalVariable = DIDescriptor;
pub type DIArray = DIDescriptor;
pub type DISubrange = DIDescriptor;

Expand Down Expand Up @@ -1589,6 +1590,18 @@ pub mod llvm {
Col: c_uint)
-> DILexicalBlock;

pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
Context: DIDescriptor,
Name: *c_char,
LinkageName: *c_char,
File: DIFile,
LineNo: c_uint,
Ty: DIType,
isLocalToUnit: bool,
Val: ValueRef,
Decl: ValueRef)
-> DIGlobalVariable;

pub fn LLVMDIBuilderCreateLocalVariable(Builder: DIBuilderRef,
Tag: c_uint,
Scope: DIDescriptor,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/middle/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use middle::trans::inline;
use middle::trans::machine;
use middle::trans::type_::Type;
use middle::trans::type_of;
use middle::trans::debuginfo;
use middle::ty;
use util::ppaux::{Repr, ty_to_str};

Expand Down Expand Up @@ -688,5 +689,6 @@ pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
if m != ast::MutMutable {
llvm::LLVMSetGlobalConstant(g, True);
}
debuginfo::create_global_var_metadata(ccx, id, g);
}
}
79 changes: 72 additions & 7 deletions src/librustc/middle/trans/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,66 @@ pub fn finalize(cx: &CrateContext) {
};
}

/// Creates debug information for the given global variable.
///
/// Adds the created metadata nodes directly to the crate's IR.
pub fn create_global_var_metadata(cx: &CrateContext,
node_id: ast::NodeId,
global: ValueRef) {
if cx.dbg_cx.is_none() {
return;
}

let var_item = cx.tcx.map.get(node_id);

let (ident, span) = match var_item {
ast_map::NodeItem(item) => {
match item.node {
ast::ItemStatic(..) => (item.ident, item.span),
_ => cx.sess().span_bug(item.span,
format!("debuginfo::create_global_var_metadata() -
Captured var-id refers to unexpected ast_item
variant: {:?}",
var_item))
}
},
_ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() - Captured var-id \
refers to unexpected ast_map variant: {:?}",
var_item))
};

let filename = span_start(cx, span).file.name.clone();
let file_metadata = file_metadata(cx, filename);

let is_local_to_unit = is_node_local_to_unit(cx, node_id);
let loc = span_start(cx, span);

let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
let type_metadata = type_metadata(cx, variable_type, span);

let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
let var_name = token::get_ident(ident).get().to_str();
let linkage_name = namespace_node.mangled_name_of_contained_item(var_name);
let var_scope = namespace_node.scope;

var_name.with_c_str(|var_name| {
linkage_name.with_c_str(|linkage_name| {
unsafe {
llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
var_scope,
var_name,
linkage_name,
file_metadata,
loc.line as c_uint,
type_metadata,
is_local_to_unit,
global,
ptr::null());
}
})
});
}

/// Creates debug information for the given local variable.
///
/// Adds the created metadata nodes directly to the crate's IR.
Expand Down Expand Up @@ -640,13 +700,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
// Clang sets this parameter to the opening brace of the function's block, so let's do this too.
let scope_line = span_start(cx, top_level_block.span).line;

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

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

fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
{
// The is_local_to_unit flag indicates whether a function is local to the current compilation
// unit (i.e. if it is *static* in the C-sense). The *reachable* set should provide a good
// approximation of this, as it contains everything that might leak out of the current crate
// (by being externally visible or by being inlined into something externally visible). It might
// better to use the `exported_items` set from `driver::CrateAnalysis` in the future, but (atm)
// this set is not available in the translation pass.
!cx.reachable.contains(&node_id)
}

fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
return unsafe {
llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
Expand Down
22 changes: 22 additions & 0 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,28 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
unwrapDI<DIFile>(File), Line, Col));
}

extern "C" LLVMValueRef LLVMDIBuilderCreateStaticVariable(
DIBuilderRef Builder,
LLVMValueRef Context,
const char* Name,
const char* LinkageName,
LLVMValueRef File,
unsigned LineNo,
LLVMValueRef Ty,
bool isLocalToUnit,
LLVMValueRef Val,
LLVMValueRef Decl = NULL) {
return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
Name,
LinkageName,
unwrapDI<DIFile>(File),
LineNo,
unwrapDI<DIType>(Ty),
isLocalToUnit,
unwrap(Val),
unwrapDI<MDNode*>(Decl)));
}

extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
DIBuilderRef Builder,
unsigned Tag,
Expand Down
1 change: 1 addition & 0 deletions src/rustllvm/rustllvm.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ LLVMDIBuilderCreate
LLVMDIBuilderDispose
LLVMDIBuilderFinalize
LLVMDIBuilderCreateCompileUnit
LLVMDIBuilderCreateStaticVariable
LLVMDIBuilderCreateLocalVariable
LLVMDIBuilderCreateFunction
LLVMDIBuilderCreateFile
Expand Down
68 changes: 68 additions & 0 deletions src/test/debug-info/basic-types-globals-metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2013-2014 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.

// ignore-android: FIXME(#10381)

// compile-flags:-g
// debugger:rbreak zzz
// debugger:run
// debugger:finish
// debugger:whatis 'basic-types-globals-metadata::B'
// check:type = bool
// debugger:whatis 'basic-types-globals-metadata::I'
// check:type = int
// debugger:whatis 'basic-types-globals-metadata::C'
// check:type = char
// debugger:whatis 'basic-types-globals-metadata::I8'
// check:type = i8
// debugger:whatis 'basic-types-globals-metadata::I16'
// check:type = i16
// debugger:whatis 'basic-types-globals-metadata::I32'
// check:type = i32
// debugger:whatis 'basic-types-globals-metadata::I64'
// check:type = i64
// debugger:whatis 'basic-types-globals-metadata::U'
// check:type = uint
// debugger:whatis 'basic-types-globals-metadata::U8'
// check:type = u8
// debugger:whatis 'basic-types-globals-metadata::U16'
// check:type = u16
// debugger:whatis 'basic-types-globals-metadata::U32'
// check:type = u32
// debugger:whatis 'basic-types-globals-metadata::U64'
// check:type = u64
// debugger:whatis 'basic-types-globals-metadata::F32'
// check:type = f32
// debugger:whatis 'basic-types-globals-metadata::F64'
// check:type = f64
// debugger:continue

#[allow(unused_variable)];

static B: bool = false;
static I: int = -1;
static C: char = 'a';
static I8: i8 = 68;
static I16: i16 = -16;
static I32: i32 = -32;
static I64: i64 = -64;
static U: uint = 1;
static U8: u8 = 100;
static U16: u16 = 16;
static U32: u32 = 32;
static U64: u64 = 64;
static F32: f32 = 2.5;
static F64: f64 = 3.5;

fn main() {
_zzz();
}

fn _zzz() {()}
74 changes: 74 additions & 0 deletions src/test/debug-info/basic-types-globals.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2013-2014 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.

// Caveats - gdb prints any 8-bit value (meaning rust I8 and u8 values)
// as its numerical value along with its associated ASCII char, there
// doesn't seem to be any way around this. Also, gdb doesn't know
// about UTF-32 character encoding and will print a rust char as only
// its numerical value.

// ignore-android: FIXME(#10381)

// compile-flags:-g
// debugger:rbreak zzz
// debugger:run
// debugger:finish
// debugger:print 'basic-types-globals::B'
// check:$1 = false
// debugger:print 'basic-types-globals::I'
// check:$2 = -1
// debugger:print 'basic-types-globals::C'
// check:$3 = 97
// debugger:print/d 'basic-types-globals::I8'
// check:$4 = 68
// debugger:print 'basic-types-globals::I16'
// check:$5 = -16
// debugger:print 'basic-types-globals::I32'
// check:$6 = -32
// debugger:print 'basic-types-globals::I64'
// check:$7 = -64
// debugger:print 'basic-types-globals::U'
// check:$8 = 1
// debugger:print/d 'basic-types-globals::U8'
// check:$9 = 100
// debugger:print 'basic-types-globals::U16'
// check:$10 = 16
// debugger:print 'basic-types-globals::U32'
// check:$11 = 32
// debugger:print 'basic-types-globals::U64'
// check:$12 = 64
// debugger:print 'basic-types-globals::F32'
// check:$13 = 2.5
// debugger:print 'basic-types-globals::F64'
// check:$14 = 3.5
// debugger:continue

#[allow(unused_variable)];

static B: bool = false;
static I: int = -1;
static C: char = 'a';
static I8: i8 = 68;
static I16: i16 = -16;
static I32: i32 = -32;
static I64: i64 = -64;
static U: uint = 1;
static U8: u8 = 100;
static U16: u16 = 16;
static U32: u32 = 32;
static U64: u64 = 64;
static F32: f32 = 2.5;
static F64: f64 = 3.5;

fn main() {
_zzz();
}

fn _zzz() {()}
3 changes: 1 addition & 2 deletions src/test/debug-info/basic-types-metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@
// check:type = f64
// debugger:info functions _yyy
// check:[...]![...]_yyy([...])([...]);
// debugger:detach
// debugger:quit
// debugger:continue

#[allow(unused_variable)];

Expand Down
Loading

0 comments on commit 3eb3a02

Please sign in to comment.