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