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