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.
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.
11 #![allow(non_upper_case_globals)]
12 #![allow(non_camel_case_types)]
13 #![allow(non_snake_case)]
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/")]
20 #![feature(box_syntax)]
21 #![feature(concat_idents)]
23 #![feature(link_args)]
24 #![feature(static_nobundle)]
26 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
27 #[allow(unused_extern_crates)]
28 extern crate rustc_cratesio_shim;
31 extern crate bitflags;
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::*;
43 use std::str::FromStr;
45 use std::ffi::{CString, CStr};
46 use std::cell::RefCell;
47 use libc::{c_uint, c_char, size_t};
56 pub fn into_result(self) -> Result<(), ()> {
58 LLVMRustResult::Success => Ok(()),
59 LLVMRustResult::Failure => Err(()),
64 pub fn AddFunctionAttrStringValue(llfn: ValueRef,
69 LLVMRustAddFunctionAttrStringValue(llfn,
76 #[derive(Copy, Clone)]
77 pub enum AttributePlace {
84 pub fn as_uint(self) -> c_uint {
86 AttributePlace::ReturnValue => 0,
87 AttributePlace::Argument(i) => 1 + i,
88 AttributePlace::Function => !0,
93 #[derive(Copy, Clone, PartialEq)]
95 pub enum CodeGenOptSize {
96 CodeGenOptSizeNone = 0,
97 CodeGenOptSizeDefault = 1,
98 CodeGenOptSizeAggressive = 2,
101 impl FromStr for ArchiveKind {
104 fn from_str(s: &str) -> Result<Self, Self::Err> {
106 "gnu" => Ok(ArchiveKind::K_GNU),
107 "bsd" => Ok(ArchiveKind::K_BSD),
108 "coff" => Ok(ArchiveKind::K_COFF),
114 #[allow(missing_copy_implementations)]
115 pub enum RustString_opaque {}
116 type RustStringRef = *mut RustString_opaque;
117 type RustStringRepr = *mut RefCell<Vec<u8>>;
119 /// Appending to a Rust string -- used by RawRustStringOstream.
121 pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: RustStringRef,
124 let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
126 let sr = sr as RustStringRepr;
127 (*sr).borrow_mut().extend_from_slice(slice);
130 pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
132 LLVMSetInstructionCallConv(instr, cc as c_uint);
135 pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
137 LLVMSetFunctionCallConv(fn_, cc as c_uint);
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
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) {
149 LLVMRustSetComdat(llmod, val, LLVMGetValueName(val));
153 pub fn UnsetComdat(val: ValueRef) {
155 LLVMRustUnsetComdat(val);
159 pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
161 LLVMSetUnnamedAddr(global, unnamed as Bool);
165 pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
167 LLVMSetThreadLocal(global, is_thread_local as Bool);
170 pub fn set_thread_local_mode(global: ValueRef, mode: ThreadLocalMode) {
172 LLVMSetThreadLocalMode(global, mode);
177 pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
178 unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) }
181 pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
182 unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) }
185 pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
186 unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) }
189 pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) {
191 self.apply_llfn(idx, llfn);
193 self.unapply_llfn(idx, llfn);
198 // Memory-managed interface to target data.
204 impl Drop for TargetData {
207 LLVMDisposeTargetData(self.lltd);
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()) } }
217 // Memory-managed interface to object files.
219 pub struct ObjectFile {
220 pub llof: ObjectFileRef,
223 unsafe impl Send for ObjectFile {}
226 // This will take ownership of llmb
227 pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
229 let llof = LLVMCreateObjectFile(llmb);
230 if llof as isize == 0 {
231 // LLVMCreateObjectFile took ownership of llmb
235 Some(ObjectFile { llof: llof })
240 impl Drop for ObjectFile {
243 LLVMDisposeObjectFile(self.llof);
248 // Memory-managed interface to section iterators.
250 pub struct SectionIter {
251 pub llsi: SectionIteratorRef,
254 impl Drop for SectionIter {
257 LLVMDisposeSectionIterator(self.llsi);
262 pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
263 unsafe { SectionIter { llsi: LLVMGetSections(llof) } }
266 /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
267 pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
269 assert!(index < LLVMCountParams(llfn),
270 "out of bounds argument access: {} out of {} arguments", index, LLVMCountParams(llfn));
271 LLVMGetParam(llfn, index)
275 fn get_params(llfn: ValueRef) -> Vec<ValueRef> {
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));
287 pub fn build_string<F>(f: F) -> Option<String>
288 where F: FnOnce(RustStringRef)
290 let mut buf = RefCell::new(Vec::new());
291 f(&mut buf as RustStringRepr as RustStringRef);
292 String::from_utf8(buf.into_inner()).ok()
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")
299 pub fn initialize_available_targets() {
300 macro_rules! init_target(
301 ($cfg:meta, $($method:ident),*) => { {
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);
391 pub fn last_error() -> Option<String> {
393 let cstr = LLVMRustGetLastError();
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 _);
405 pub struct OperandBundleDef {
406 inner: OperandBundleDefRef,
409 impl OperandBundleDef {
410 pub fn new(name: &str, vals: &[ValueRef]) -> OperandBundleDef {
411 let name = CString::new(name).unwrap();
413 LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
415 OperandBundleDef { inner: def }
418 pub fn raw(&self) -> OperandBundleDefRef {
423 impl Drop for OperandBundleDef {
426 LLVMRustFreeOperandBundleDef(self.inner);