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