1 //! LLVM diagnostic reports.
3 pub use self::Diagnostic::*;
4 pub use self::OptimizationDiagnosticKind::*;
6 use crate::value::Value;
9 use super::{DiagnosticInfo, SMDiagnostic};
10 use rustc_span::InnerSpan;
12 #[derive(Copy, Clone)]
13 pub enum OptimizationDiagnosticKind {
17 OptimizationAnalysisFPCommute,
18 OptimizationAnalysisAliasing,
20 OptimizationRemarkOther,
23 impl OptimizationDiagnosticKind {
24 pub fn describe(self) -> &'static str {
26 OptimizationRemark | OptimizationRemarkOther => "remark",
27 OptimizationMissed => "missed",
28 OptimizationAnalysis => "analysis",
29 OptimizationAnalysisFPCommute => "floating-point",
30 OptimizationAnalysisAliasing => "aliasing",
31 OptimizationFailure => "failure",
36 pub struct OptimizationDiagnostic<'ll> {
37 pub kind: OptimizationDiagnosticKind,
38 pub pass_name: String,
39 pub function: &'ll Value,
46 impl<'ll> OptimizationDiagnostic<'ll> {
47 unsafe fn unpack(kind: OptimizationDiagnosticKind, di: &'ll DiagnosticInfo) -> Self {
48 let mut function = None;
52 let mut message = None;
53 let mut filename = None;
54 let pass_name = super::build_string(|pass_name| {
55 message = super::build_string(|message| {
56 filename = super::build_string(|filename| {
57 super::LLVMRustUnpackOptimizationDiagnostic(
73 let mut filename = filename.unwrap_or_default();
74 if filename.is_empty() {
75 filename.push_str("<unknown file>");
78 OptimizationDiagnostic {
80 pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"),
81 function: function.unwrap(),
85 message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM"),
90 pub struct SrcMgrDiagnostic {
91 pub level: super::DiagnosticLevel,
93 pub source: Option<(String, Vec<InnerSpan>)>,
96 impl SrcMgrDiagnostic {
97 pub unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
98 // Recover the post-substitution assembly code from LLVM for better
100 let mut have_source = false;
101 let mut buffer = String::new();
102 let mut level = super::DiagnosticLevel::Error;
104 let mut ranges = [0; 8];
105 let mut num_ranges = ranges.len() / 2;
106 let message = super::build_string(|message| {
107 buffer = super::build_string(|buffer| {
108 have_source = super::LLVMRustUnpackSMDiagnostic(
118 .expect("non-UTF8 inline asm");
120 .expect("non-UTF8 SMDiagnostic");
125 source: have_source.then(|| {
126 let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
127 for i in 0..num_ranges {
128 spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
137 pub struct InlineAsmDiagnostic {
138 pub level: super::DiagnosticLevel,
141 pub source: Option<(String, Vec<InnerSpan>)>,
144 impl InlineAsmDiagnostic {
145 unsafe fn unpackInlineAsm(di: &DiagnosticInfo) -> Self {
147 let mut message = None;
148 let mut level = super::DiagnosticLevel::Error;
150 super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
152 InlineAsmDiagnostic {
155 message: super::twine_to_string(message.unwrap()),
160 unsafe fn unpackSrcMgr(di: &DiagnosticInfo) -> Self {
162 let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
163 InlineAsmDiagnostic {
166 message: smdiag.message,
167 source: smdiag.source,
172 pub enum Diagnostic<'ll> {
173 Optimization(OptimizationDiagnostic<'ll>),
174 InlineAsm(InlineAsmDiagnostic),
175 PGO(&'ll DiagnosticInfo),
176 Linker(&'ll DiagnosticInfo),
177 Unsupported(&'ll DiagnosticInfo),
179 /// LLVM has other types that we do not wrap here.
180 UnknownDiagnostic(&'ll DiagnosticInfo),
183 impl<'ll> Diagnostic<'ll> {
184 pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
185 use super::DiagnosticKind as Dk;
186 let kind = super::LLVMRustGetDiagInfoKind(di);
189 Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
191 Dk::OptimizationRemark => {
192 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
194 Dk::OptimizationRemarkOther => {
195 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
197 Dk::OptimizationRemarkMissed => {
198 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
201 Dk::OptimizationRemarkAnalysis => {
202 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
205 Dk::OptimizationRemarkAnalysisFPCommute => {
206 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
209 Dk::OptimizationRemarkAnalysisAliasing => {
210 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
213 Dk::OptimizationFailure => {
214 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
217 Dk::PGOProfile => PGO(di),
218 Dk::Linker => Linker(di),
219 Dk::Unsupported => Unsupported(di),
221 Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
223 _ => UnknownDiagnostic(di),