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