| //! LLVM diagnostic reports. |
| |
| pub use self::Diagnostic::*; |
| pub use self::OptimizationDiagnosticKind::*; |
| |
| use crate::value::Value; |
| use libc::c_uint; |
| |
| use super::{DiagnosticInfo, Twine}; |
| |
| #[derive(Copy, Clone)] |
| pub enum OptimizationDiagnosticKind { |
| OptimizationRemark, |
| OptimizationMissed, |
| OptimizationAnalysis, |
| OptimizationAnalysisFPCommute, |
| OptimizationAnalysisAliasing, |
| OptimizationFailure, |
| OptimizationRemarkOther, |
| } |
| |
| impl OptimizationDiagnosticKind { |
| pub fn describe(self) -> &'static str { |
| match self { |
| OptimizationRemark | OptimizationRemarkOther => "remark", |
| OptimizationMissed => "missed", |
| OptimizationAnalysis => "analysis", |
| OptimizationAnalysisFPCommute => "floating-point", |
| OptimizationAnalysisAliasing => "aliasing", |
| OptimizationFailure => "failure", |
| } |
| } |
| } |
| |
| pub struct OptimizationDiagnostic<'ll> { |
| pub kind: OptimizationDiagnosticKind, |
| pub pass_name: String, |
| pub function: &'ll Value, |
| pub line: c_uint, |
| pub column: c_uint, |
| pub filename: String, |
| pub message: String, |
| } |
| |
| impl OptimizationDiagnostic<'ll> { |
| unsafe fn unpack(kind: OptimizationDiagnosticKind, di: &'ll DiagnosticInfo) -> Self { |
| let mut function = None; |
| let mut line = 0; |
| let mut column = 0; |
| |
| let mut message = None; |
| let mut filename = None; |
| let pass_name = super::build_string(|pass_name| { |
| message = super::build_string(|message| { |
| filename = super::build_string(|filename| { |
| super::LLVMRustUnpackOptimizationDiagnostic( |
| di, |
| pass_name, |
| &mut function, |
| &mut line, |
| &mut column, |
| filename, |
| message, |
| ) |
| }) |
| .ok() |
| }) |
| .ok() |
| }) |
| .ok(); |
| |
| let mut filename = filename.unwrap_or_default(); |
| if filename.is_empty() { |
| filename.push_str("<unknown file>"); |
| } |
| |
| OptimizationDiagnostic { |
| kind, |
| pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"), |
| function: function.unwrap(), |
| line, |
| column, |
| filename, |
| message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM"), |
| } |
| } |
| } |
| |
| #[derive(Copy, Clone)] |
| pub struct InlineAsmDiagnostic<'ll> { |
| pub level: super::DiagnosticLevel, |
| pub cookie: c_uint, |
| pub message: &'ll Twine, |
| pub instruction: Option<&'ll Value>, |
| } |
| |
| impl InlineAsmDiagnostic<'ll> { |
| unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self { |
| let mut cookie = 0; |
| let mut message = None; |
| let mut instruction = None; |
| let mut level = super::DiagnosticLevel::Error; |
| |
| super::LLVMRustUnpackInlineAsmDiagnostic( |
| di, |
| &mut level, |
| &mut cookie, |
| &mut message, |
| &mut instruction, |
| ); |
| |
| InlineAsmDiagnostic { level, cookie, message: message.unwrap(), instruction } |
| } |
| } |
| |
| pub enum Diagnostic<'ll> { |
| Optimization(OptimizationDiagnostic<'ll>), |
| InlineAsm(InlineAsmDiagnostic<'ll>), |
| PGO(&'ll DiagnosticInfo), |
| Linker(&'ll DiagnosticInfo), |
| |
| /// LLVM has other types that we do not wrap here. |
| UnknownDiagnostic(&'ll DiagnosticInfo), |
| } |
| |
| impl Diagnostic<'ll> { |
| pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self { |
| use super::DiagnosticKind as Dk; |
| let kind = super::LLVMRustGetDiagInfoKind(di); |
| |
| match kind { |
| Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)), |
| |
| Dk::OptimizationRemark => { |
| Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)) |
| } |
| Dk::OptimizationRemarkOther => { |
| Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di)) |
| } |
| Dk::OptimizationRemarkMissed => { |
| Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di)) |
| } |
| |
| Dk::OptimizationRemarkAnalysis => { |
| Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di)) |
| } |
| |
| Dk::OptimizationRemarkAnalysisFPCommute => { |
| Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di)) |
| } |
| |
| Dk::OptimizationRemarkAnalysisAliasing => { |
| Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di)) |
| } |
| |
| Dk::OptimizationFailure => { |
| Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)) |
| } |
| |
| Dk::PGOProfile => PGO(di), |
| Dk::Linker => Linker(di), |
| |
| _ => UnknownDiagnostic(di), |
| } |
| } |
| } |