]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/llvm/diagnostic.rs
Rollup merge of #69579 - petrochenkov:noprevspan, r=Centril
[rust.git] / src / librustc_codegen_llvm / llvm / diagnostic.rs
1 //! LLVM diagnostic reports.
2
3 pub use self::Diagnostic::*;
4 pub use self::OptimizationDiagnosticKind::*;
5
6 use crate::value::Value;
7 use libc::c_uint;
8
9 use super::{DiagnosticInfo, Twine};
10
11 #[derive(Copy, Clone)]
12 pub enum OptimizationDiagnosticKind {
13     OptimizationRemark,
14     OptimizationMissed,
15     OptimizationAnalysis,
16     OptimizationAnalysisFPCommute,
17     OptimizationAnalysisAliasing,
18     OptimizationFailure,
19     OptimizationRemarkOther,
20 }
21
22 impl OptimizationDiagnosticKind {
23     pub fn describe(self) -> &'static str {
24         match self {
25             OptimizationRemark | OptimizationRemarkOther => "remark",
26             OptimizationMissed => "missed",
27             OptimizationAnalysis => "analysis",
28             OptimizationAnalysisFPCommute => "floating-point",
29             OptimizationAnalysisAliasing => "aliasing",
30             OptimizationFailure => "failure",
31         }
32     }
33 }
34
35 pub struct OptimizationDiagnostic<'ll> {
36     pub kind: OptimizationDiagnosticKind,
37     pub pass_name: String,
38     pub function: &'ll Value,
39     pub line: c_uint,
40     pub column: c_uint,
41     pub filename: String,
42     pub message: String,
43 }
44
45 impl OptimizationDiagnostic<'ll> {
46     unsafe fn unpack(kind: OptimizationDiagnosticKind, di: &'ll DiagnosticInfo) -> Self {
47         let mut function = None;
48         let mut line = 0;
49         let mut column = 0;
50
51         let mut message = None;
52         let mut filename = None;
53         let pass_name = super::build_string(|pass_name| {
54             message = super::build_string(|message| {
55                 filename = super::build_string(|filename| {
56                     super::LLVMRustUnpackOptimizationDiagnostic(
57                         di,
58                         pass_name,
59                         &mut function,
60                         &mut line,
61                         &mut column,
62                         filename,
63                         message,
64                     )
65                 })
66                 .ok()
67             })
68             .ok()
69         })
70         .ok();
71
72         let mut filename = filename.unwrap_or_default();
73         if filename.is_empty() {
74             filename.push_str("<unknown file>");
75         }
76
77         OptimizationDiagnostic {
78             kind,
79             pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"),
80             function: function.unwrap(),
81             line,
82             column,
83             filename,
84             message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM"),
85         }
86     }
87 }
88
89 #[derive(Copy, Clone)]
90 pub struct InlineAsmDiagnostic<'ll> {
91     pub cookie: c_uint,
92     pub message: &'ll Twine,
93     pub instruction: Option<&'ll Value>,
94 }
95
96 impl InlineAsmDiagnostic<'ll> {
97     unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
98         let mut cookie = 0;
99         let mut message = None;
100         let mut instruction = None;
101
102         super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut cookie, &mut message, &mut instruction);
103
104         InlineAsmDiagnostic { cookie, message: message.unwrap(), instruction }
105     }
106 }
107
108 pub enum Diagnostic<'ll> {
109     Optimization(OptimizationDiagnostic<'ll>),
110     InlineAsm(InlineAsmDiagnostic<'ll>),
111     PGO(&'ll DiagnosticInfo),
112     Linker(&'ll DiagnosticInfo),
113
114     /// LLVM has other types that we do not wrap here.
115     UnknownDiagnostic(&'ll DiagnosticInfo),
116 }
117
118 impl Diagnostic<'ll> {
119     pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
120         use super::DiagnosticKind as Dk;
121         let kind = super::LLVMRustGetDiagInfoKind(di);
122
123         match kind {
124             Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
125
126             Dk::OptimizationRemark => {
127                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
128             }
129             Dk::OptimizationRemarkOther => {
130                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
131             }
132             Dk::OptimizationRemarkMissed => {
133                 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
134             }
135
136             Dk::OptimizationRemarkAnalysis => {
137                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
138             }
139
140             Dk::OptimizationRemarkAnalysisFPCommute => {
141                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
142             }
143
144             Dk::OptimizationRemarkAnalysisAliasing => {
145                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
146             }
147
148             Dk::OptimizationFailure => {
149                 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
150             }
151
152             Dk::PGOProfile => PGO(di),
153             Dk::Linker => Linker(di),
154
155             _ => UnknownDiagnostic(di),
156         }
157     }
158 }