]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/llvm/diagnostic.rs
rustc: Handle linker diagnostic from LLVM
[rust.git] / src / librustc_codegen_llvm / llvm / diagnostic.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! LLVM diagnostic reports.
12
13 pub use self::OptimizationDiagnosticKind::*;
14 pub use self::Diagnostic::*;
15
16 use libc::c_uint;
17 use value::Value;
18
19 use super::{DiagnosticInfo, Twine};
20
21 #[derive(Copy, Clone)]
22 pub enum OptimizationDiagnosticKind {
23     OptimizationRemark,
24     OptimizationMissed,
25     OptimizationAnalysis,
26     OptimizationAnalysisFPCommute,
27     OptimizationAnalysisAliasing,
28     OptimizationFailure,
29     OptimizationRemarkOther,
30 }
31
32 impl OptimizationDiagnosticKind {
33     pub fn describe(self) -> &'static str {
34         match self {
35             OptimizationRemark | OptimizationRemarkOther => "remark",
36             OptimizationMissed => "missed",
37             OptimizationAnalysis => "analysis",
38             OptimizationAnalysisFPCommute => "floating-point",
39             OptimizationAnalysisAliasing => "aliasing",
40             OptimizationFailure => "failure",
41         }
42     }
43 }
44
45 pub struct OptimizationDiagnostic<'ll> {
46     pub kind: OptimizationDiagnosticKind,
47     pub pass_name: String,
48     pub function: &'ll Value,
49     pub line: c_uint,
50     pub column: c_uint,
51     pub filename: String,
52     pub message: String,
53 }
54
55 impl OptimizationDiagnostic<'ll> {
56     unsafe fn unpack(
57         kind: OptimizationDiagnosticKind,
58         di: &'ll DiagnosticInfo,
59     ) -> Self {
60         let mut function = None;
61         let mut line = 0;
62         let mut column = 0;
63
64         let mut message = None;
65         let mut filename = None;
66         let pass_name = super::build_string(|pass_name|
67             message = super::build_string(|message|
68                 filename = super::build_string(|filename|
69                     super::LLVMRustUnpackOptimizationDiagnostic(di,
70                                                                 pass_name,
71                                                                 &mut function,
72                                                                 &mut line,
73                                                                 &mut column,
74                                                                 filename,
75                                                                 message)
76                 ).ok()
77             ).ok()
78         ).ok();
79
80         let mut filename = filename.unwrap_or(String::new());
81         if filename.is_empty() {
82             filename.push_str("<unknown file>");
83         }
84
85         OptimizationDiagnostic {
86             kind,
87             pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"),
88             function: function.unwrap(),
89             line,
90             column,
91             filename,
92             message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM")
93         }
94     }
95 }
96
97 #[derive(Copy, Clone)]
98 pub struct InlineAsmDiagnostic<'ll> {
99     pub cookie: c_uint,
100     pub message: &'ll Twine,
101     pub instruction: &'ll Value,
102 }
103
104 impl InlineAsmDiagnostic<'ll> {
105     unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
106         let mut cookie = 0;
107         let mut message = None;
108         let mut instruction = None;
109
110         super::LLVMRustUnpackInlineAsmDiagnostic(
111             di,
112             &mut cookie,
113             &mut message,
114             &mut instruction,
115         );
116
117         InlineAsmDiagnostic {
118             cookie,
119             message: message.unwrap(),
120             instruction: instruction.unwrap(),
121         }
122     }
123 }
124
125 pub enum Diagnostic<'ll> {
126     Optimization(OptimizationDiagnostic<'ll>),
127     InlineAsm(InlineAsmDiagnostic<'ll>),
128     PGO(&'ll DiagnosticInfo),
129     Linker(&'ll DiagnosticInfo),
130
131     /// LLVM has other types that we do not wrap here.
132     UnknownDiagnostic(&'ll DiagnosticInfo),
133 }
134
135 impl Diagnostic<'ll> {
136     pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
137         use super::DiagnosticKind as Dk;
138         let kind = super::LLVMRustGetDiagInfoKind(di);
139
140         match kind {
141             Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
142
143             Dk::OptimizationRemark => {
144                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
145             }
146             Dk::OptimizationRemarkOther => {
147                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
148             }
149             Dk::OptimizationRemarkMissed => {
150                 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
151             }
152
153             Dk::OptimizationRemarkAnalysis => {
154                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
155             }
156
157             Dk::OptimizationRemarkAnalysisFPCommute => {
158                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
159             }
160
161             Dk::OptimizationRemarkAnalysisAliasing => {
162                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
163             }
164
165             Dk::OptimizationFailure => {
166                 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
167             }
168
169             Dk::PGOProfile => {
170                 PGO(di)
171             }
172             Dk::Linker => {
173                 Linker(di)
174             }
175
176             _ => UnknownDiagnostic(di),
177         }
178     }
179 }