提交 2ec959fc 编写于 作者: N Niko Matsakis

extend MIR dump with detailed, extra information

上级 e5dc4ba2
......@@ -11,7 +11,8 @@
use rustc::hir;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::mir::*;
use rustc::ty::TyCtxt;
use rustc::mir::visit::Visitor;
use rustc::ty::{self, TyCtxt};
use rustc::ty::item_path;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
......@@ -125,14 +126,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
F: FnMut(PassWhere, &mut Write) -> io::Result<()>,
{
let _: io::Result<()> = do catch {
let mut file = create_dump_file(
tcx,
"mir",
pass_num,
pass_name,
disambiguator,
source,
)?;
let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?;
writeln!(file, "// MIR for `{}`", node_path)?;
writeln!(file, "// source = {:?}", source)?;
writeln!(file, "// pass_name = {}", pass_name)?;
......@@ -148,15 +142,9 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
};
if tcx.sess.opts.debugging_opts.dump_mir_graphviz {
let _: io::Result<()> = do catch {
let mut file = create_dump_file(
tcx,
"dot",
pass_num,
pass_name,
disambiguator,
source,
)?;
let _: io::Result<()> = do catch {
let mut file =
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
Ok(())
};
......@@ -297,10 +285,10 @@ pub fn write_mir_fn<'a, 'gcx, 'tcx, F>(
}
/// Write out a human-readable textual representation for the given basic block.
pub fn write_basic_block<F>(
tcx: TyCtxt,
pub fn write_basic_block<'cx, 'gcx, 'tcx, F>(
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
block: BasicBlock,
mir: &Mir,
mir: &Mir<'tcx>,
extra_data: &mut F,
w: &mut Write,
) -> io::Result<()>
......@@ -330,6 +318,11 @@ pub fn write_basic_block<F>(
comment(tcx, statement.source_info),
A = ALIGN,
)?;
write_extra(tcx, w, |visitor| {
visitor.visit_statement(current_location.block, statement, current_location);
})?;
extra_data(PassWhere::AfterLocation(current_location), w)?;
current_location.statement_index += 1;
......@@ -346,11 +339,93 @@ pub fn write_basic_block<F>(
comment(tcx, data.terminator().source_info),
A = ALIGN,
)?;
write_extra(tcx, w, |visitor| {
visitor.visit_terminator(current_location.block, data.terminator(), current_location);
})?;
extra_data(PassWhere::AfterLocation(current_location), w)?;
writeln!(w, "{}}}", INDENT)
}
/// After we print the main statement, we sometimes dump extra
/// information. There's often a lot of little things "nuzzled up" in
/// a statement.
fn write_extra<'cx, 'gcx, 'tcx, F>(
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
write: &mut Write,
mut visit_op: F,
) -> io::Result<()>
where F: FnMut(&mut ExtraComments<'cx, 'gcx, 'tcx>)
{
let mut extra_comments = ExtraComments {
_tcx: tcx,
comments: vec![],
};
visit_op(&mut extra_comments);
for comment in extra_comments.comments {
writeln!(write, "{:A$} // {}", "", comment, A = ALIGN)?;
}
Ok(())
}
struct ExtraComments<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
_tcx: TyCtxt<'cx, 'gcx, 'tcx>, // don't need it now, but bet we will soon
comments: Vec<String>,
}
impl<'cx, 'gcx, 'tcx> ExtraComments<'cx, 'gcx, 'tcx> {
fn push(&mut self, lines: &str) {
for line in lines.split("\n") {
self.comments.push(line.to_string());
}
}
}
impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> {
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
self.super_constant(constant, location);
let Constant { span, ty, literal } = constant;
self.push(&format!("mir::Constant"));
self.push(&format!("└ span: {:?}", span));
self.push(&format!("└ ty: {:?}", ty));
self.push(&format!("└ literal: {:?}", literal));
}
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
self.super_const(constant);
let ty::Const { ty, val } = constant;
self.push(&format!("ty::Const"));
self.push(&format!("└ ty: {:?}", ty));
self.push(&format!("└ val: {:?}", val));
}
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
self.super_rvalue(rvalue, location);
match rvalue {
Rvalue::Aggregate(kind, _) => match **kind {
AggregateKind::Closure(def_id, substs) => {
self.push(&format!("closure"));
self.push(&format!("└ def_id: {:?}", def_id));
self.push(&format!("└ substs: {:#?}", substs));
}
AggregateKind::Generator(def_id, substs, interior) => {
self.push(&format!("generator"));
self.push(&format!("└ def_id: {:?}", def_id));
self.push(&format!("└ substs: {:#?}", substs));
self.push(&format!("└ interior: {:?}", interior));
}
_ => {}
},
_ => {}
}
}
}
fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String {
format!(
"scope {} at {}",
......
......@@ -2535,7 +2535,10 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &[ExpectedL
let mut dumped_file = fs::File::open(output_file.clone()).unwrap();
let mut dumped_string = String::new();
dumped_file.read_to_string(&mut dumped_string).unwrap();
let mut dumped_lines = dumped_string.lines().filter(|l| !l.is_empty());
let mut dumped_lines = dumped_string
.lines()
.map(|l| nocomment_mir_line(l))
.filter(|l| !l.is_empty());
let mut expected_lines = expected_content
.iter()
.filter(|&l| {
......@@ -2573,7 +2576,7 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &[ExpectedL
.join("\n");
panic!(
"Did not find expected line, error: {}\n\
Actual Line: {:?}\n\
Expected Line: {:?}\n\
Expected:\n{}\n\
Actual:\n{}",
extra_msg,
......@@ -2599,7 +2602,9 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &[ExpectedL
error(
expected_line,
format!(
"Mismatch in lines\nCurrnt block: {}\nExpected Line: {:?}",
"Mismatch in lines\n\
Current block: {}\n\
Actual Line: {:?}",
start_block_line.unwrap_or("None"),
dumped_line
),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册