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 pub struct OptimizationDiagnostic<'ll> {
24 pub kind: OptimizationDiagnosticKind,
25 pub pass_name: String,
26 pub function: &'ll Value,
33 impl<'ll> OptimizationDiagnostic<'ll> {
34 unsafe fn unpack(kind: OptimizationDiagnosticKind, di: &'ll DiagnosticInfo) -> Self {
35 let mut function = None;
39 let mut message = None;
40 let mut filename = None;
41 let pass_name = super::build_string(|pass_name| {
42 message = super::build_string(|message| {
43 filename = super::build_string(|filename| {
44 super::LLVMRustUnpackOptimizationDiagnostic(
60 let mut filename = filename.unwrap_or_default();
61 if filename.is_empty() {
62 filename.push_str("<unknown file>");
65 OptimizationDiagnostic {
67 pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"),
68 function: function.unwrap(),
72 message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM"),
77 pub struct SrcMgrDiagnostic {
78 pub level: super::DiagnosticLevel,
80 pub source: Option<(String, Vec<InnerSpan>)>,
83 impl SrcMgrDiagnostic {
84 pub unsafe fn unpack(diag: &SMDiagnostic) -> SrcMgrDiagnostic {
85 // Recover the post-substitution assembly code from LLVM for better
87 let mut have_source = false;
88 let mut buffer = String::new();
89 let mut level = super::DiagnosticLevel::Error;
91 let mut ranges = [0; 8];
92 let mut num_ranges = ranges.len() / 2;
93 let message = super::build_string(|message| {
94 buffer = super::build_string(|buffer| {
95 have_source = super::LLVMRustUnpackSMDiagnostic(
105 .expect("non-UTF8 inline asm");
107 .expect("non-UTF8 SMDiagnostic");
112 source: have_source.then(|| {
113 let mut spans = vec![InnerSpan::new(loc as usize, loc as usize)];
114 for i in 0..num_ranges {
115 spans.push(InnerSpan::new(ranges[i * 2] as usize, ranges[i * 2 + 1] as usize));
124 pub struct InlineAsmDiagnostic {
125 pub level: super::DiagnosticLevel,
128 pub source: Option<(String, Vec<InnerSpan>)>,
131 impl InlineAsmDiagnostic {
132 unsafe fn unpackInlineAsm(di: &DiagnosticInfo) -> Self {
134 let mut message = None;
135 let mut level = super::DiagnosticLevel::Error;
137 super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
139 InlineAsmDiagnostic {
142 message: super::twine_to_string(message.unwrap()),
147 unsafe fn unpackSrcMgr(di: &DiagnosticInfo) -> Self {
149 let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
150 InlineAsmDiagnostic {
153 message: smdiag.message,
154 source: smdiag.source,
159 pub enum Diagnostic<'ll> {
160 Optimization(OptimizationDiagnostic<'ll>),
161 InlineAsm(InlineAsmDiagnostic),
162 PGO(&'ll DiagnosticInfo),
163 Linker(&'ll DiagnosticInfo),
164 Unsupported(&'ll DiagnosticInfo),
166 /// LLVM has other types that we do not wrap here.
167 UnknownDiagnostic(&'ll DiagnosticInfo),
170 impl<'ll> Diagnostic<'ll> {
171 pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
172 use super::DiagnosticKind as Dk;
173 let kind = super::LLVMRustGetDiagInfoKind(di);
176 Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
178 Dk::OptimizationRemark => {
179 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
181 Dk::OptimizationRemarkOther => {
182 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
184 Dk::OptimizationRemarkMissed => {
185 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
188 Dk::OptimizationRemarkAnalysis => {
189 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
192 Dk::OptimizationRemarkAnalysisFPCommute => {
193 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
196 Dk::OptimizationRemarkAnalysisAliasing => {
197 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
200 Dk::OptimizationFailure => {
201 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
204 Dk::PGOProfile => PGO(di),
205 Dk::Linker => Linker(di),
206 Dk::Unsupported => Unsupported(di),
208 Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
210 _ => UnknownDiagnostic(di),