]> git.lizzy.rs Git - rust.git/blob - src/librustc_llvm/diagnostic.rs
Auto merge of #45075 - alexcrichton:inline-less, r=michaelwoerister
[rust.git] / src / librustc_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 std::ptr;
18
19 use {DiagnosticInfoRef, TwineRef, ValueRef};
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 {
46     pub kind: OptimizationDiagnosticKind,
47     pub pass_name: String,
48     pub function: ValueRef,
49     pub line: c_uint,
50     pub column: c_uint,
51     pub filename: String,
52     pub message: String,
53 }
54
55 impl OptimizationDiagnostic {
56     unsafe fn unpack(kind: OptimizationDiagnosticKind,
57                      di: DiagnosticInfoRef)
58                      -> OptimizationDiagnostic {
59         let mut function = ptr::null_mut();
60         let mut line = 0;
61         let mut column = 0;
62
63         let mut message = None;
64         let mut filename = None;
65         let pass_name = super::build_string(|pass_name|
66             message = super::build_string(|message|
67                 filename = super::build_string(|filename|
68                     super::LLVMRustUnpackOptimizationDiagnostic(di,
69                                                                 pass_name,
70                                                                 &mut function,
71                                                                 &mut line,
72                                                                 &mut column,
73                                                                 filename,
74                                                                 message)
75                 )
76             )
77         );
78
79         let mut filename = filename.unwrap_or(String::new());
80         if filename.is_empty() {
81             filename.push_str("<unknown file>");
82         }
83
84         OptimizationDiagnostic {
85             kind,
86             pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"),
87             function,
88             line,
89             column,
90             filename,
91             message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM")
92         }
93     }
94 }
95
96 #[derive(Copy, Clone)]
97 pub struct InlineAsmDiagnostic {
98     pub cookie: c_uint,
99     pub message: TwineRef,
100     pub instruction: ValueRef,
101 }
102
103 impl InlineAsmDiagnostic {
104     unsafe fn unpack(di: DiagnosticInfoRef) -> InlineAsmDiagnostic {
105
106         let mut opt = InlineAsmDiagnostic {
107             cookie: 0,
108             message: ptr::null_mut(),
109             instruction: ptr::null_mut(),
110         };
111
112         super::LLVMRustUnpackInlineAsmDiagnostic(di,
113                                                  &mut opt.cookie,
114                                                  &mut opt.message,
115                                                  &mut opt.instruction);
116
117         opt
118     }
119 }
120
121 pub enum Diagnostic {
122     Optimization(OptimizationDiagnostic),
123     InlineAsm(InlineAsmDiagnostic),
124
125     /// LLVM has other types that we do not wrap here.
126     UnknownDiagnostic(DiagnosticInfoRef),
127 }
128
129 impl Diagnostic {
130     pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic {
131         use super::DiagnosticKind as Dk;
132         let kind = super::LLVMRustGetDiagInfoKind(di);
133
134         match kind {
135             Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
136
137             Dk::OptimizationRemark => {
138                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
139             }
140             Dk::OptimizationRemarkOther => {
141                 Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
142             }
143             Dk::OptimizationRemarkMissed => {
144                 Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
145             }
146
147             Dk::OptimizationRemarkAnalysis => {
148                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
149             }
150
151             Dk::OptimizationRemarkAnalysisFPCommute => {
152                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
153             }
154
155             Dk::OptimizationRemarkAnalysisAliasing => {
156                 Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
157             }
158
159             Dk::OptimizationFailure => {
160                 Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
161             }
162
163             _ => UnknownDiagnostic(di),
164         }
165     }
166 }