1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! Utility routines for pretty-printing error messages.

use ir;
use ir::entities::Inst;
use ir::function::Function;
use isa::TargetIsa;
use result::CodegenError;
use std::fmt;
use std::fmt::Write;
use std::string::{String, ToString};
use verifier::VerifierError;
use write::decorate_function;

/// Pretty-print a verifier error.
pub fn pretty_verifier_error(
    func: &ir::Function,
    isa: Option<&TargetIsa>,
    err: &VerifierError,
) -> String {
    let mut w = String::new();
    decorate_function(
        &mut |w, func, isa, inst, indent| pretty_function_error(w, func, isa, inst, indent, err),
        &mut w,
        func,
        isa,
    ).unwrap();
    w
}

/// Pretty-print a function verifier error.
fn pretty_function_error(
    w: &mut Write,
    func: &Function,
    isa: Option<&TargetIsa>,
    cur_inst: Inst,
    indent: usize,
    err: &VerifierError,
) -> fmt::Result {
    match err.location {
        ir::entities::AnyEntity::Inst(inst) => {
            if inst == cur_inst {
                write!(
                    w,
                    "{1:0$}{2}\n",
                    indent,
                    "",
                    func.dfg.display_inst(cur_inst, isa)
                )?;
                write!(w, "{1:0$}{2}", indent, "", "^")?;
                for _c in cur_inst.to_string().chars() {
                    write!(w, "~")?;
                }
                write!(w, "\n\nverifier {}\n\n", err.to_string())
            } else {
                write!(
                    w,
                    "{1:0$}{2}\n",
                    indent,
                    "",
                    func.dfg.display_inst(cur_inst, isa)
                )
            }
        }
        _ => write!(w, "{}", "\n"),
    }
}

/// Pretty-print a Cranelift error.
pub fn pretty_error(func: &ir::Function, isa: Option<&TargetIsa>, err: CodegenError) -> String {
    if let CodegenError::Verifier(e) = err {
        pretty_verifier_error(func, isa, &e)
    } else {
        err.to_string()
    }
}