debuginfo: Fix name attribute for DWARF compile units
This commit is contained in:
parent
d39b6060f0
commit
0a03bc073a
|
@ -897,35 +897,48 @@ pub fn build_session_options(binary: ~str,
|
|||
return sopts;
|
||||
}
|
||||
|
||||
pub fn build_session(sopts: @session::Options, demitter: @diagnostic::Emitter)
|
||||
pub fn build_session(sopts: @session::Options,
|
||||
local_crate_source_file: Option<Path>,
|
||||
demitter: @diagnostic::Emitter)
|
||||
-> Session {
|
||||
let codemap = @codemap::CodeMap::new();
|
||||
let diagnostic_handler =
|
||||
diagnostic::mk_handler(Some(demitter));
|
||||
let span_diagnostic_handler =
|
||||
diagnostic::mk_span_handler(diagnostic_handler, codemap);
|
||||
build_session_(sopts, codemap, demitter, span_diagnostic_handler)
|
||||
|
||||
build_session_(sopts, local_crate_source_file, codemap, demitter, span_diagnostic_handler)
|
||||
}
|
||||
|
||||
pub fn build_session_(sopts: @session::Options,
|
||||
cm: @codemap::CodeMap,
|
||||
local_crate_source_file: Option<Path>,
|
||||
codemap: @codemap::CodeMap,
|
||||
demitter: @diagnostic::Emitter,
|
||||
span_diagnostic_handler: @diagnostic::SpanHandler)
|
||||
-> Session {
|
||||
let target_cfg = build_target_config(sopts, demitter);
|
||||
let p_s = parse::new_parse_sess_special_handler(span_diagnostic_handler,
|
||||
cm);
|
||||
let p_s = parse::new_parse_sess_special_handler(span_diagnostic_handler, codemap);
|
||||
let cstore = @CStore::new(token::get_ident_interner());
|
||||
let filesearch = @filesearch::FileSearch::new(
|
||||
&sopts.maybe_sysroot,
|
||||
sopts.target_triple,
|
||||
sopts.addl_lib_search_paths);
|
||||
|
||||
// Make the path absolute, if necessary
|
||||
let local_crate_source_file = local_crate_source_file.map(|path|
|
||||
if path.is_absolute() {
|
||||
path.clone()
|
||||
} else {
|
||||
os::getcwd().join(path.clone())
|
||||
}
|
||||
);
|
||||
|
||||
@Session_ {
|
||||
targ_cfg: target_cfg,
|
||||
opts: sopts,
|
||||
cstore: cstore,
|
||||
parse_sess: p_s,
|
||||
codemap: cm,
|
||||
codemap: codemap,
|
||||
// For a library crate, this is always none
|
||||
entry_fn: RefCell::new(None),
|
||||
entry_type: Cell::new(None),
|
||||
|
@ -933,6 +946,7 @@ pub fn build_session_(sopts: @session::Options,
|
|||
span_diagnostic: span_diagnostic_handler,
|
||||
filesearch: filesearch,
|
||||
building_library: Cell::new(false),
|
||||
local_crate_source_file: local_crate_source_file,
|
||||
working_dir: os::getcwd(),
|
||||
lints: RefCell::new(HashMap::new()),
|
||||
node_id: Cell::new(1),
|
||||
|
@ -1164,13 +1178,8 @@ mod test {
|
|||
Ok(m) => m,
|
||||
Err(f) => fail!("test_switch_implies_cfg_test: {}", f.to_err_msg())
|
||||
};
|
||||
let sessopts = build_session_options(
|
||||
~"rustc",
|
||||
matches,
|
||||
@diagnostic::DefaultEmitter as @diagnostic::Emitter);
|
||||
let sess = build_session(sessopts,
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter);
|
||||
let sessopts = build_session_options(~"rustc", matches, @diagnostic::DefaultEmitter);
|
||||
let sess = build_session(sessopts, None, @diagnostic::DefaultEmitter);
|
||||
let cfg = build_configuration(sess);
|
||||
assert!((attr::contains_name(cfg, "test")));
|
||||
}
|
||||
|
@ -1187,13 +1196,8 @@ mod test {
|
|||
f.to_err_msg());
|
||||
}
|
||||
};
|
||||
let sessopts = build_session_options(
|
||||
~"rustc",
|
||||
matches,
|
||||
@diagnostic::DefaultEmitter as @diagnostic::Emitter);
|
||||
let sess = build_session(sessopts,
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter);
|
||||
let sessopts = build_session_options(~"rustc", matches, @diagnostic::DefaultEmitter);
|
||||
let sess = build_session(sessopts, None, @diagnostic::DefaultEmitter);
|
||||
let cfg = build_configuration(sess);
|
||||
let mut test_items = cfg.iter().filter(|m| "test" == m.name());
|
||||
assert!(test_items.next().is_some());
|
||||
|
|
|
@ -211,6 +211,9 @@ pub struct Session_ {
|
|||
macro_registrar_fn: RefCell<Option<ast::DefId>>,
|
||||
filesearch: @filesearch::FileSearch,
|
||||
building_library: Cell<bool>,
|
||||
// The name of the root source file of the crate, in the local file system. The path is always
|
||||
// expected to be absolute. `None` means that there is no source file.
|
||||
local_crate_source_file: Option<Path>,
|
||||
working_dir: Path,
|
||||
lints: RefCell<HashMap<ast::NodeId,
|
||||
~[(lint::Lint, codemap::Span, ~str)]>>,
|
||||
|
|
|
@ -230,22 +230,22 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
|
|||
version(binary);
|
||||
return;
|
||||
}
|
||||
let input = match matches.free.len() {
|
||||
let (input, input_file_path) = match matches.free.len() {
|
||||
0u => d::early_error(demitter, "no input filename given"),
|
||||
1u => {
|
||||
let ifile = matches.free[0].as_slice();
|
||||
if "-" == ifile {
|
||||
let src = str::from_utf8_owned(io::stdin().read_to_end()).unwrap();
|
||||
d::StrInput(src.to_managed())
|
||||
(d::StrInput(src.to_managed()), None)
|
||||
} else {
|
||||
d::FileInput(Path::new(ifile))
|
||||
(d::FileInput(Path::new(ifile)), Some(Path::new(ifile)))
|
||||
}
|
||||
}
|
||||
_ => d::early_error(demitter, "multiple input filenames provided")
|
||||
};
|
||||
|
||||
let sopts = d::build_session_options(binary, matches, demitter);
|
||||
let sess = d::build_session(sopts, demitter);
|
||||
let sess = d::build_session(sopts, input_file_path, demitter);
|
||||
let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
|
||||
let ofile = matches.opt_str("o").map(|o| Path::new(o));
|
||||
let cfg = d::build_configuration(sess);
|
||||
|
|
|
@ -165,7 +165,7 @@ impl CrateContext {
|
|||
|
||||
let (crate_map_name, crate_map) = decl_crate_map(sess, link_meta.clone(), llmod);
|
||||
let dbg_cx = if sess.opts.debuginfo {
|
||||
Some(debuginfo::CrateDebugContext::new(llmod, name.to_owned()))
|
||||
Some(debuginfo::CrateDebugContext::new(llmod))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
|
@ -142,7 +142,7 @@ use middle::ty;
|
|||
use middle::pat_util;
|
||||
use util::ppaux;
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::c_str::{CString, ToCStr};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::hashmap::HashMap;
|
||||
use std::hashmap::HashSet;
|
||||
|
@ -173,7 +173,6 @@ static DW_ATE_unsigned_char: c_uint = 0x08;
|
|||
|
||||
/// A context object for maintaining all state needed by the debuginfo module.
|
||||
pub struct CrateDebugContext {
|
||||
priv crate_file: ~str,
|
||||
priv llcontext: ContextRef,
|
||||
priv builder: DIBuilderRef,
|
||||
priv current_debug_location: Cell<DebugLocation>,
|
||||
|
@ -186,13 +185,12 @@ pub struct CrateDebugContext {
|
|||
}
|
||||
|
||||
impl CrateDebugContext {
|
||||
pub fn new(llmod: ModuleRef, crate: ~str) -> CrateDebugContext {
|
||||
pub fn new(llmod: ModuleRef) -> CrateDebugContext {
|
||||
debug!("CrateDebugContext::new");
|
||||
let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
|
||||
// DIBuilder inherits context from the module, so we'd better use the same one
|
||||
let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
|
||||
return CrateDebugContext {
|
||||
crate_file: crate,
|
||||
llcontext: llcontext,
|
||||
builder: builder,
|
||||
current_debug_location: Cell::new(UnknownLocation),
|
||||
|
@ -929,26 +927,49 @@ fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
|
|||
};
|
||||
}
|
||||
|
||||
fn compile_unit_metadata(cx: @CrateContext) {
|
||||
let dcx = debug_context(cx);
|
||||
let crate_name: &str = dcx.crate_file;
|
||||
fn compile_unit_metadata(cx: &CrateContext) {
|
||||
let work_dir = &cx.sess.working_dir;
|
||||
let compile_unit_name = match cx.sess.local_crate_source_file {
|
||||
None => fallback_path(cx),
|
||||
Some(ref abs_path) => {
|
||||
if abs_path.is_relative() {
|
||||
cx.sess.warn("debuginfo: Invalid path to crate's local root source file!");
|
||||
fallback_path(cx)
|
||||
} else {
|
||||
match abs_path.path_relative_from(work_dir) {
|
||||
Some(ref p) if p.is_relative() => {
|
||||
// prepend "./" if necessary
|
||||
let dotdot = bytes!("..");
|
||||
let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
|
||||
let mut path_bytes = p.as_vec().to_owned();
|
||||
|
||||
debug!("compile_unit_metadata: {:?}", crate_name);
|
||||
if path_bytes.slice_to(2) != prefix &&
|
||||
path_bytes.slice_to(2) != dotdot {
|
||||
path_bytes.insert(0, prefix[0]);
|
||||
path_bytes.insert(1, prefix[1]);
|
||||
}
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let work_dir = cx.sess.working_dir.as_str().unwrap();
|
||||
path_bytes.to_c_str()
|
||||
}
|
||||
_ => fallback_path(cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
debug!("compile_unit_metadata: {:?}", compile_unit_name);
|
||||
let producer = format!("rustc version {}", env!("CFG_VERSION"));
|
||||
|
||||
crate_name.with_c_str(|crate_name| {
|
||||
work_dir.with_c_str(|work_dir| {
|
||||
compile_unit_name.with_ref(|compile_unit_name| {
|
||||
work_dir.as_vec().with_c_str(|work_dir| {
|
||||
producer.with_c_str(|producer| {
|
||||
"".with_c_str(|flags| {
|
||||
"".with_c_str(|split_name| {
|
||||
unsafe {
|
||||
llvm::LLVMDIBuilderCreateCompileUnit(
|
||||
dcx.builder,
|
||||
debug_context(cx).builder,
|
||||
DW_LANG_RUST,
|
||||
crate_name,
|
||||
compile_unit_name,
|
||||
work_dir,
|
||||
producer,
|
||||
cx.sess.opts.optimize != session::No,
|
||||
|
@ -961,6 +982,10 @@ fn compile_unit_metadata(cx: @CrateContext) {
|
|||
})
|
||||
})
|
||||
});
|
||||
|
||||
fn fallback_path(cx: &CrateContext) -> CString {
|
||||
cx.link_meta.crateid.name.to_c_str()
|
||||
}
|
||||
}
|
||||
|
||||
fn declare_local(bcx: &Block,
|
||||
|
|
|
@ -52,7 +52,7 @@ fn setup_env(test_name: &str, source_string: &str) -> Env {
|
|||
let matches = getopts(~[~"-Z", ~"verbose"], optgroups()).get();
|
||||
let diag = diagnostic::collect(messages);
|
||||
let sessopts = build_session_options(~"rustc", &matches, diag);
|
||||
let sess = build_session(sessopts, diag);
|
||||
let sess = build_session(sessopts, None, diag);
|
||||
let cfg = build_configuration(sess, ~"whatever", str_input(~""));
|
||||
let dm = HashMap();
|
||||
let amap = HashMap();
|
||||
|
|
|
@ -64,9 +64,9 @@ fn get_ast_and_resolve(cpath: &Path,
|
|||
syntax::diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
|
||||
|
||||
let sess = driver::driver::build_session_(sessopts,
|
||||
Some(cpath.clone()),
|
||||
parsesess.cm,
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter,
|
||||
@diagnostic::DefaultEmitter,
|
||||
span_diagnostic_handler);
|
||||
|
||||
let mut cfg = build_configuration(sess);
|
||||
|
|
|
@ -34,7 +34,8 @@ use visit_ast::RustdocVisitor;
|
|||
|
||||
pub fn run(input: &str, matches: &getopts::Matches) -> int {
|
||||
let parsesess = parse::new_parse_sess(None);
|
||||
let input = driver::FileInput(Path::new(input));
|
||||
let input_path = Path::new(input);
|
||||
let input = driver::FileInput(input_path.clone());
|
||||
let libs = matches.opt_strs("L").map(|s| Path::new(s.as_slice()));
|
||||
let libs = @RefCell::new(libs.move_iter().collect());
|
||||
|
||||
|
@ -52,9 +53,9 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
|
|||
diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
|
||||
|
||||
let sess = driver::build_session_(sessopts,
|
||||
Some(input_path),
|
||||
parsesess.cm,
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter,
|
||||
@diagnostic::DefaultEmitter,
|
||||
span_diagnostic_handler);
|
||||
|
||||
let cfg = driver::build_configuration(sess);
|
||||
|
@ -113,9 +114,9 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
|
|||
diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
|
||||
|
||||
let sess = driver::build_session_(sessopts,
|
||||
None,
|
||||
parsesess.cm,
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter,
|
||||
@diagnostic::DefaultEmitter,
|
||||
span_diagnostic_handler);
|
||||
|
||||
let outdir = TempDir::new("rustdoctest").expect("rustdoc needs a tempdir");
|
||||
|
|
|
@ -114,8 +114,8 @@ impl<'a> PkgScript<'a> {
|
|||
};
|
||||
let input = driver::FileInput(script.clone());
|
||||
let sess = driver::build_session(options,
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter);
|
||||
Some(script.clone()),
|
||||
@diagnostic::DefaultEmitter);
|
||||
let cfg = driver::build_configuration(sess);
|
||||
let crate = driver::phase_1_parse_input(sess, cfg.clone(), &input);
|
||||
let loader = &mut Loader::new(sess);
|
||||
|
|
|
@ -1770,11 +1770,8 @@ fn test_linker_build() {
|
|||
let matches = getopts([], optgroups());
|
||||
let options = build_session_options(~"rustpkg",
|
||||
matches.as_ref().unwrap(),
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter);
|
||||
let sess = build_session(options,
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter);
|
||||
@diagnostic::DefaultEmitter);
|
||||
let sess = build_session(options, None, @diagnostic::DefaultEmitter);
|
||||
let test_sys = test_sysroot();
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let cc = get_cc_prog(sess);
|
||||
|
|
|
@ -264,6 +264,7 @@ pub fn compile_input(context: &BuildContext,
|
|||
debug!("About to build session...");
|
||||
|
||||
let sess = driver::build_session(options,
|
||||
Some(in_file.clone()),
|
||||
@diagnostic::DefaultEmitter as
|
||||
@diagnostic::Emitter);
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
fn main() {
|
||||
let args : ~[~str] = ::std::os::args();
|
||||
::std::io::println(args[0]);
|
||||
}
|
||||
|
||||
|
||||
// xfail-android: FIXME(#10381)
|
||||
|
||||
// This test case checks whether compile unit names are set correctly, so that the correct default
|
||||
// source file can be found.
|
||||
|
||||
// compile-flags:-Z extra-debug-info
|
||||
// debugger:list
|
||||
// check:1[...]fn main() {
|
||||
// check:2[...]let args : ~[~str] = ::std::os::args();
|
||||
// check:3[...]::std::io::println(args[0]);
|
||||
// check:4[...]}
|
||||
|
||||
// Copyright 2013 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.
|
Loading…
Reference in New Issue