]> git.lizzy.rs Git - rust.git/blob - src/librustc_llvm/lib.rs
rustc: Remove #![unstable] annotation
[rust.git] / src / librustc_llvm / lib.rs
1 // Copyright 2012-2015 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 #![allow(non_upper_case_globals)]
12 #![allow(non_camel_case_types)]
13 #![allow(non_snake_case)]
14 #![allow(dead_code)]
15
16 #![crate_name = "rustc_llvm"]
17 #![crate_type = "dylib"]
18 #![crate_type = "rlib"]
19 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
20        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
21        html_root_url = "https://doc.rust-lang.org/nightly/")]
22 #![deny(warnings)]
23
24 #![feature(associated_consts)]
25 #![feature(box_syntax)]
26 #![feature(concat_idents)]
27 #![feature(libc)]
28 #![feature(link_args)]
29 #![feature(static_nobundle)]
30
31 #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
32 #![cfg_attr(stage0, feature(rustc_private))]
33 #![cfg_attr(stage0, feature(staged_api))]
34
35 extern crate libc;
36 #[macro_use]
37 #[no_link]
38 extern crate rustc_bitflags;
39
40 pub use self::IntPredicate::*;
41 pub use self::RealPredicate::*;
42 pub use self::TypeKind::*;
43 pub use self::AtomicRmwBinOp::*;
44 pub use self::MetadataType::*;
45 pub use self::CodeGenOptSize::*;
46 pub use self::DiagnosticKind::*;
47 pub use self::CallConv::*;
48 pub use self::DiagnosticSeverity::*;
49 pub use self::Linkage::*;
50
51 use std::str::FromStr;
52 use std::slice;
53 use std::ffi::{CString, CStr};
54 use std::cell::RefCell;
55 use libc::{c_uint, c_char, size_t};
56
57 pub mod archive_ro;
58 pub mod diagnostic;
59 pub mod ffi;
60
61 pub use ffi::*;
62
63 impl LLVMRustResult {
64     pub fn into_result(self) -> Result<(), ()> {
65         match self {
66             LLVMRustResult::Success => Ok(()),
67             LLVMRustResult::Failure => Err(()),
68         }
69     }
70 }
71
72 pub fn AddFunctionAttrStringValue(llfn: ValueRef,
73                                   idx: AttributePlace,
74                                   attr: &CStr,
75                                   value: &CStr) {
76     unsafe {
77         LLVMRustAddFunctionAttrStringValue(llfn,
78                                            idx.as_uint(),
79                                            attr.as_ptr(),
80                                            value.as_ptr())
81     }
82 }
83
84 #[repr(C)]
85 #[derive(Copy, Clone)]
86 pub enum AttributePlace {
87     Argument(u32),
88     Function,
89 }
90
91 impl AttributePlace {
92     pub fn ReturnValue() -> Self {
93         AttributePlace::Argument(0)
94     }
95
96     pub fn as_uint(self) -> c_uint {
97         match self {
98             AttributePlace::Function => !0,
99             AttributePlace::Argument(i) => i,
100         }
101     }
102 }
103
104 #[derive(Copy, Clone, PartialEq)]
105 #[repr(C)]
106 pub enum CodeGenOptSize {
107     CodeGenOptSizeNone = 0,
108     CodeGenOptSizeDefault = 1,
109     CodeGenOptSizeAggressive = 2,
110 }
111
112 impl FromStr for ArchiveKind {
113     type Err = ();
114
115     fn from_str(s: &str) -> Result<Self, Self::Err> {
116         match s {
117             "gnu" => Ok(ArchiveKind::K_GNU),
118             "mips64" => Ok(ArchiveKind::K_MIPS64),
119             "bsd" => Ok(ArchiveKind::K_BSD),
120             "coff" => Ok(ArchiveKind::K_COFF),
121             _ => Err(()),
122         }
123     }
124 }
125
126 #[allow(missing_copy_implementations)]
127 pub enum RustString_opaque {}
128 pub type RustStringRef = *mut RustString_opaque;
129 type RustStringRepr = *mut RefCell<Vec<u8>>;
130
131 /// Appending to a Rust string -- used by RawRustStringOstream.
132 #[no_mangle]
133 pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: RustStringRef,
134                                                  ptr: *const c_char,
135                                                  size: size_t) {
136     let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
137
138     let sr = sr as RustStringRepr;
139     (*sr).borrow_mut().extend_from_slice(slice);
140 }
141
142 pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
143     unsafe {
144         LLVMSetInstructionCallConv(instr, cc as c_uint);
145     }
146 }
147 pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
148     unsafe {
149         LLVMSetFunctionCallConv(fn_, cc as c_uint);
150     }
151 }
152
153 // Externally visible symbols that might appear in multiple translation units need to appear in
154 // their own comdat section so that the duplicates can be discarded at link time. This can for
155 // example happen for generics when using multiple codegen units. This function simply uses the
156 // value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
157 // function.
158 // For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
159 pub fn SetUniqueComdat(llmod: ModuleRef, val: ValueRef) {
160     unsafe {
161         LLVMRustSetComdat(llmod, val, LLVMGetValueName(val));
162     }
163 }
164
165 pub fn UnsetComdat(val: ValueRef) {
166     unsafe {
167         LLVMRustUnsetComdat(val);
168     }
169 }
170
171 pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
172     unsafe {
173         LLVMSetUnnamedAddr(global, unnamed as Bool);
174     }
175 }
176
177 pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
178     unsafe {
179         LLVMSetThreadLocal(global, is_thread_local as Bool);
180     }
181 }
182
183 impl Attribute {
184     pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
185         unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) }
186     }
187
188     pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
189         unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) }
190     }
191
192     pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
193         unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) }
194     }
195
196     pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) {
197         if set {
198             self.apply_llfn(idx, llfn);
199         } else {
200             self.unapply_llfn(idx, llfn);
201         }
202     }
203 }
204
205 // Memory-managed interface to target data.
206
207 pub struct TargetData {
208     pub lltd: TargetDataRef,
209 }
210
211 impl Drop for TargetData {
212     fn drop(&mut self) {
213         unsafe {
214             LLVMDisposeTargetData(self.lltd);
215         }
216     }
217 }
218
219 pub fn mk_target_data(string_rep: &str) -> TargetData {
220     let string_rep = CString::new(string_rep).unwrap();
221     TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) } }
222 }
223
224 // Memory-managed interface to object files.
225
226 pub struct ObjectFile {
227     pub llof: ObjectFileRef,
228 }
229
230 impl ObjectFile {
231     // This will take ownership of llmb
232     pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
233         unsafe {
234             let llof = LLVMCreateObjectFile(llmb);
235             if llof as isize == 0 {
236                 // LLVMCreateObjectFile took ownership of llmb
237                 return None;
238             }
239
240             Some(ObjectFile { llof: llof })
241         }
242     }
243 }
244
245 impl Drop for ObjectFile {
246     fn drop(&mut self) {
247         unsafe {
248             LLVMDisposeObjectFile(self.llof);
249         }
250     }
251 }
252
253 // Memory-managed interface to section iterators.
254
255 pub struct SectionIter {
256     pub llsi: SectionIteratorRef,
257 }
258
259 impl Drop for SectionIter {
260     fn drop(&mut self) {
261         unsafe {
262             LLVMDisposeSectionIterator(self.llsi);
263         }
264     }
265 }
266
267 pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
268     unsafe { SectionIter { llsi: LLVMGetSections(llof) } }
269 }
270
271 /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
272 pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
273     unsafe {
274         assert!(index < LLVMCountParams(llfn),
275             "out of bounds argument access: {} out of {} arguments", index, LLVMCountParams(llfn));
276         LLVMGetParam(llfn, index)
277     }
278 }
279
280 pub fn get_params(llfn: ValueRef) -> Vec<ValueRef> {
281     unsafe {
282         let num_params = LLVMCountParams(llfn);
283         let mut params = Vec::with_capacity(num_params as usize);
284         for idx in 0..num_params {
285             params.push(LLVMGetParam(llfn, idx));
286         }
287
288         params
289     }
290 }
291
292 pub fn build_string<F>(f: F) -> Option<String>
293     where F: FnOnce(RustStringRef)
294 {
295     let mut buf = RefCell::new(Vec::new());
296     f(&mut buf as RustStringRepr as RustStringRef);
297     String::from_utf8(buf.into_inner()).ok()
298 }
299
300 pub unsafe fn twine_to_string(tr: TwineRef) -> String {
301     build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM")
302 }
303
304 pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
305     build_string(|s| LLVMRustWriteDebugLocToString(c, tr, s))
306         .expect("got a non-UTF8 DebugLoc from LLVM")
307 }
308
309 pub fn initialize_available_targets() {
310     macro_rules! init_target(
311         ($cfg:meta, $($method:ident),*) => { {
312             #[cfg($cfg)]
313             fn init() {
314                 extern {
315                     $(fn $method();)*
316                 }
317                 unsafe {
318                     $($method();)*
319                 }
320             }
321             #[cfg(not($cfg))]
322             fn init() { }
323             init();
324         } }
325     );
326     init_target!(llvm_component = "x86",
327                  LLVMInitializeX86TargetInfo,
328                  LLVMInitializeX86Target,
329                  LLVMInitializeX86TargetMC,
330                  LLVMInitializeX86AsmPrinter,
331                  LLVMInitializeX86AsmParser);
332     init_target!(llvm_component = "arm",
333                  LLVMInitializeARMTargetInfo,
334                  LLVMInitializeARMTarget,
335                  LLVMInitializeARMTargetMC,
336                  LLVMInitializeARMAsmPrinter,
337                  LLVMInitializeARMAsmParser);
338     init_target!(llvm_component = "aarch64",
339                  LLVMInitializeAArch64TargetInfo,
340                  LLVMInitializeAArch64Target,
341                  LLVMInitializeAArch64TargetMC,
342                  LLVMInitializeAArch64AsmPrinter,
343                  LLVMInitializeAArch64AsmParser);
344     init_target!(llvm_component = "mips",
345                  LLVMInitializeMipsTargetInfo,
346                  LLVMInitializeMipsTarget,
347                  LLVMInitializeMipsTargetMC,
348                  LLVMInitializeMipsAsmPrinter,
349                  LLVMInitializeMipsAsmParser);
350     init_target!(llvm_component = "powerpc",
351                  LLVMInitializePowerPCTargetInfo,
352                  LLVMInitializePowerPCTarget,
353                  LLVMInitializePowerPCTargetMC,
354                  LLVMInitializePowerPCAsmPrinter,
355                  LLVMInitializePowerPCAsmParser);
356     init_target!(llvm_component = "pnacl",
357                  LLVMInitializePNaClTargetInfo,
358                  LLVMInitializePNaClTarget,
359                  LLVMInitializePNaClTargetMC);
360     init_target!(llvm_component = "systemz",
361                  LLVMInitializeSystemZTargetInfo,
362                  LLVMInitializeSystemZTarget,
363                  LLVMInitializeSystemZTargetMC,
364                  LLVMInitializeSystemZAsmPrinter,
365                  LLVMInitializeSystemZAsmParser);
366     init_target!(llvm_component = "jsbackend",
367                  LLVMInitializeJSBackendTargetInfo,
368                  LLVMInitializeJSBackendTarget,
369                  LLVMInitializeJSBackendTargetMC);
370     init_target!(llvm_component = "msp430",
371                  LLVMInitializeMSP430TargetInfo,
372                  LLVMInitializeMSP430Target,
373                  LLVMInitializeMSP430TargetMC,
374                  LLVMInitializeMSP430AsmPrinter);
375     init_target!(llvm_component = "sparc",
376                  LLVMInitializeSparcTargetInfo,
377                  LLVMInitializeSparcTarget,
378                  LLVMInitializeSparcTargetMC,
379                  LLVMInitializeSparcAsmPrinter,
380                  LLVMInitializeSparcAsmParser);
381     init_target!(llvm_component = "nvptx",
382                  LLVMInitializeNVPTXTargetInfo,
383                  LLVMInitializeNVPTXTarget,
384                  LLVMInitializeNVPTXTargetMC,
385                  LLVMInitializeNVPTXAsmPrinter);
386     init_target!(llvm_component = "hexagon",
387                  LLVMInitializeHexagonTargetInfo,
388                  LLVMInitializeHexagonTarget,
389                  LLVMInitializeHexagonTargetMC,
390                  LLVMInitializeHexagonAsmPrinter,
391                  LLVMInitializeHexagonAsmParser);
392 }
393
394 pub fn last_error() -> Option<String> {
395     unsafe {
396         let cstr = LLVMRustGetLastError();
397         if cstr.is_null() {
398             None
399         } else {
400             let err = CStr::from_ptr(cstr).to_bytes();
401             let err = String::from_utf8_lossy(err).to_string();
402             libc::free(cstr as *mut _);
403             Some(err)
404         }
405     }
406 }
407
408 pub struct OperandBundleDef {
409     inner: OperandBundleDefRef,
410 }
411
412 impl OperandBundleDef {
413     pub fn new(name: &str, vals: &[ValueRef]) -> OperandBundleDef {
414         let name = CString::new(name).unwrap();
415         let def = unsafe {
416             LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
417         };
418         OperandBundleDef { inner: def }
419     }
420
421     pub fn raw(&self) -> OperandBundleDefRef {
422         self.inner
423     }
424 }
425
426 impl Drop for OperandBundleDef {
427     fn drop(&mut self) {
428         unsafe {
429             LLVMRustFreeOperandBundleDef(self.inner);
430         }
431     }
432 }