use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
use util::ppaux;
+use util::common::path2cstr;
use libc::{c_uint, c_longlong};
-use std::ffi::CString;
use std::cell::{Cell, RefCell};
+use std::ffi::CString;
+use std::path::Path;
use std::ptr;
use std::rc::{Rc, Weak};
use syntax::util::interner::Interner;
fn_metadata: DISubprogram,
argument_counter: Cell<uint>,
source_locations_enabled: Cell<bool>,
+ source_location_override: Cell<bool>,
}
enum VariableAccess<'a> {
return;
}
FunctionDebugContext::RegularContext(box ref function_debug_context) => {
+ if function_debug_context.source_location_override.get() {
+ // Just ignore any attempts to set a new debug location while
+ // the override is active.
+ return;
+ }
+
let cx = fcx.ccx;
debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
}
}
+ /// This function makes sure that all debug locations emitted while executing
+ /// `wrapped_function` are set to the given `debug_loc`.
+ pub fn with_source_location_override<F, R>(fcx: &FunctionContext,
+ debug_loc: DebugLoc,
+ wrapped_function: F) -> R
+ where F: FnOnce() -> R
+ {
+ match fcx.debug_context {
+ FunctionDebugContext::DebugInfoDisabled => {
+ wrapped_function()
+ }
+ FunctionDebugContext::FunctionWithoutDebugInfo => {
+ set_debug_location(fcx.ccx, UnknownLocation);
+ wrapped_function()
+ }
+ FunctionDebugContext::RegularContext(box ref function_debug_context) => {
+ if function_debug_context.source_location_override.get() {
+ wrapped_function()
+ } else {
+ debug_loc.apply(fcx);
+ function_debug_context.source_location_override.set(true);
+ let result = wrapped_function();
+ function_debug_context.source_location_override.set(false);
+ result
+ }
+ }
+ }
+ }
+
/// Clears the current debug location.
///
/// Instructions generated hereafter won't be assigned a source location.
fn_metadata: fn_metadata,
argument_counter: Cell::new(1),
source_locations_enabled: Cell::new(false),
+ source_location_override: Cell::new(false),
};
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) {
+ match abs_path.relative_from(work_dir) {
Some(ref p) if p.is_relative() => {
- // prepend "./" if necessary
- let dotdot = b"..";
- let prefix: &[u8] = &[dotdot[0], ::std::old_path::SEP_BYTE];
- let mut path_bytes = p.as_vec().to_vec();
-
- if &path_bytes[..2] != prefix &&
- &path_bytes[..2] != dotdot {
- path_bytes.insert(0, prefix[0]);
- path_bytes.insert(1, prefix[1]);
+ if p.starts_with(Path::new("./")) {
+ path2cstr(p)
+ } else {
+ path2cstr(&Path::new(".").join(p))
}
-
- CString::new(path_bytes).unwrap()
}
_ => fallback_path(cx)
}
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
let compile_unit_name = compile_unit_name.as_ptr();
- let work_dir = CString::new(work_dir.as_vec()).unwrap();
+ let work_dir = path2cstr(&work_dir);
let producer = CString::new(producer).unwrap();
let flags = "\0";
let split_name = "\0";
debug!("file_metadata: {}", full_path);
// FIXME (#9639): This needs to handle non-utf8 paths
- let work_dir = cx.sess().working_dir.as_str().unwrap();
+ let work_dir = cx.sess().working_dir.to_str().unwrap();
let file_name =
if full_path.starts_with(work_dir) {
&full_path[work_dir.len() + 1..full_path.len()]