]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/llvm/diagnostic.rs
Rollup merge of #74136 - JohnTitor:index-page-link, r=GuillaumeGomez
[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 level: super::DiagnosticLevel,
92     pub cookie: c_uint,
93     pub message: &'ll Twine,
94     pub instruction: Option<&'ll Value>,
95 }
96
97 impl InlineAsmDiagnostic<'ll> {
98     unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
99         let mut cookie = 0;
100         let mut message = None;
101         let mut instruction = None;
102         let mut level = super::DiagnosticLevel::Error;
103
104         super::LLVMRustUnpackInlineAsmDiagnostic(
105             di,
106             &mut level,
107             &mut cookie,
108             &mut message,
109             &mut instruction,
110         );
111
112         InlineAsmDiagnostic { level, cookie, message: message.unwrap(), instruction }
113     }
114 }
115
116 pub enum Diagnostic<'ll> {
117     Optimization(OptimizationDiagnostic<'ll>),
118     InlineAsm(InlineAsmDiagnostic<'ll>),
119     PGO(&'ll DiagnosticInfo),
120     Linker(&'ll DiagnosticInfo),
121
122     /// LLVM has other types that we do not wrap here.
123     UnknownDiagnostic(&'ll DiagnosticInfo),
124 }
125
126 impl Diagnostic<'ll> {
127     pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
128         use super::DiagnosticKind as Dk;
129         let kind = super::LLVMRustGetDiagInfoKind(di);
130
131         match kind {
132             Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
133
134             Dk::OptimizationRemark => {
135                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
136             }
137             Dk::OptimizationRemarkOther => {
138                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
139             }
140             Dk::OptimizationRemarkMissed => {
141                 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
142             }
143
144             Dk::OptimizationRemarkAnalysis => {
145                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
146             }
147
148             Dk::OptimizationRemarkAnalysisFPCommute => {
149                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
150             }
151
152             Dk::OptimizationRemarkAnalysisAliasing => {
153                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
154             }
155
156             Dk::OptimizationFailure => {
157                 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
158             }
159
160             Dk::PGOProfile => PGO(di),
161             Dk::Linker => Linker(di),
162
163             _ => UnknownDiagnostic(di),
164         }
165     }
166 }