2020-10-23 06:11:38 +00:00
|
|
|
use super::graph::CoverageGraph;
|
2020-10-23 07:45:07 +00:00
|
|
|
use super::spans::CoverageSpan;
|
|
|
|
|
|
|
|
use crate::util::pretty;
|
|
|
|
use crate::util::spanview::{self, SpanViewable};
|
|
|
|
|
|
|
|
use rustc_middle::mir::{self, TerminatorKind};
|
|
|
|
use rustc_middle::ty::TyCtxt;
|
|
|
|
|
|
|
|
/// Generates the MIR pass `CoverageSpan`-specific spanview dump file.
|
|
|
|
pub(crate) fn dump_coverage_spanview(
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
mir_body: &mir::Body<'tcx>,
|
2020-10-23 06:11:38 +00:00
|
|
|
basic_coverage_blocks: &CoverageGraph,
|
2020-10-23 07:45:07 +00:00
|
|
|
pass_name: &str,
|
|
|
|
coverage_spans: &Vec<CoverageSpan>,
|
|
|
|
) {
|
|
|
|
let mir_source = mir_body.source;
|
|
|
|
let def_id = mir_source.def_id();
|
|
|
|
|
|
|
|
let span_viewables = span_viewables(tcx, mir_body, basic_coverage_blocks, &coverage_spans);
|
|
|
|
let mut file = pretty::create_dump_file(tcx, "html", None, pass_name, &0, mir_source)
|
|
|
|
.expect("Unexpected error creating MIR spanview HTML file");
|
|
|
|
let crate_name = tcx.crate_name(def_id.krate);
|
|
|
|
let item_name = tcx.def_path(def_id).to_filename_friendly_no_crate();
|
|
|
|
let title = format!("{}.{} - Coverage Spans", crate_name, item_name);
|
|
|
|
spanview::write_document(tcx, def_id, span_viewables, &title, &mut file)
|
|
|
|
.expect("Unexpected IO error dumping coverage spans as HTML");
|
|
|
|
}
|
|
|
|
|
2020-10-23 06:11:38 +00:00
|
|
|
/// Converts the computed `BasicCoverageBlockData`s into `SpanViewable`s.
|
2020-10-23 07:45:07 +00:00
|
|
|
fn span_viewables(
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
mir_body: &mir::Body<'tcx>,
|
2020-10-23 06:11:38 +00:00
|
|
|
basic_coverage_blocks: &CoverageGraph,
|
2020-10-23 07:45:07 +00:00
|
|
|
coverage_spans: &Vec<CoverageSpan>,
|
|
|
|
) -> Vec<SpanViewable> {
|
|
|
|
let mut span_viewables = Vec::new();
|
|
|
|
for coverage_span in coverage_spans {
|
|
|
|
let tooltip = coverage_span.format_coverage_statements(tcx, mir_body);
|
2020-10-23 06:11:38 +00:00
|
|
|
let CoverageSpan { span, bcb, .. } = coverage_span;
|
|
|
|
let bcb_data = &basic_coverage_blocks[*bcb];
|
|
|
|
let id = bcb_data.id();
|
|
|
|
let leader_bb = bcb_data.leader_bb();
|
2020-10-23 07:45:07 +00:00
|
|
|
span_viewables.push(SpanViewable { bb: leader_bb, span: *span, id, tooltip });
|
|
|
|
}
|
|
|
|
span_viewables
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns a simple string representation of a `TerminatorKind` variant, indenpendent of any
|
|
|
|
/// values it might hold.
|
|
|
|
pub(crate) fn term_type(kind: &TerminatorKind<'tcx>) -> &'static str {
|
|
|
|
match kind {
|
|
|
|
TerminatorKind::Goto { .. } => "Goto",
|
|
|
|
TerminatorKind::SwitchInt { .. } => "SwitchInt",
|
|
|
|
TerminatorKind::Resume => "Resume",
|
|
|
|
TerminatorKind::Abort => "Abort",
|
|
|
|
TerminatorKind::Return => "Return",
|
|
|
|
TerminatorKind::Unreachable => "Unreachable",
|
|
|
|
TerminatorKind::Drop { .. } => "Drop",
|
|
|
|
TerminatorKind::DropAndReplace { .. } => "DropAndReplace",
|
|
|
|
TerminatorKind::Call { .. } => "Call",
|
|
|
|
TerminatorKind::Assert { .. } => "Assert",
|
|
|
|
TerminatorKind::Yield { .. } => "Yield",
|
|
|
|
TerminatorKind::GeneratorDrop => "GeneratorDrop",
|
|
|
|
TerminatorKind::FalseEdge { .. } => "FalseEdge",
|
|
|
|
TerminatorKind::FalseUnwind { .. } => "FalseUnwind",
|
|
|
|
TerminatorKind::InlineAsm { .. } => "InlineAsm",
|
|
|
|
}
|
|
|
|
}
|