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 #![crate_name = "rustc_llvm"]
17 #![crate_type = "dylib"]
18 #![crate_type = "rlib"]
19 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
20 html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
21 html_root_url = "https://doc.rust-lang.org/nightly/")]
24 #![feature(associated_consts)]
25 #![feature(box_syntax)]
26 #![feature(concat_idents)]
28 #![feature(link_args)]
29 #![feature(static_nobundle)]
31 #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))]
32 #![cfg_attr(stage0, feature(rustc_private))]
33 #![cfg_attr(stage0, feature(staged_api))]
38 extern crate rustc_bitflags;
40 pub use self::IntPredicate::*;
41 pub use self::RealPredicate::*;
42 pub use self::TypeKind::*;
43 pub use self::AtomicRmwBinOp::*;
44 pub use self::MetadataType::*;
45 pub use self::CodeGenOptSize::*;
46 pub use self::DiagnosticKind::*;
47 pub use self::CallConv::*;
48 pub use self::DiagnosticSeverity::*;
49 pub use self::Linkage::*;
51 use std::str::FromStr;
53 use std::ffi::{CString, CStr};
54 use std::cell::RefCell;
55 use libc::{c_uint, c_char, size_t};
64 pub fn into_result(self) -> Result<(), ()> {
66 LLVMRustResult::Success => Ok(()),
67 LLVMRustResult::Failure => Err(()),
72 pub fn AddFunctionAttrStringValue(llfn: ValueRef,
77 LLVMRustAddFunctionAttrStringValue(llfn,
85 #[derive(Copy, Clone)]
86 pub enum AttributePlace {
92 pub fn ReturnValue() -> Self {
93 AttributePlace::Argument(0)
96 pub fn as_uint(self) -> c_uint {
98 AttributePlace::Function => !0,
99 AttributePlace::Argument(i) => i,
104 #[derive(Copy, Clone, PartialEq)]
106 pub enum CodeGenOptSize {
107 CodeGenOptSizeNone = 0,
108 CodeGenOptSizeDefault = 1,
109 CodeGenOptSizeAggressive = 2,
112 impl FromStr for ArchiveKind {
115 fn from_str(s: &str) -> Result<Self, Self::Err> {
117 "gnu" => Ok(ArchiveKind::K_GNU),
118 "mips64" => Ok(ArchiveKind::K_MIPS64),
119 "bsd" => Ok(ArchiveKind::K_BSD),
120 "coff" => Ok(ArchiveKind::K_COFF),
126 #[allow(missing_copy_implementations)]
127 pub enum RustString_opaque {}
128 pub type RustStringRef = *mut RustString_opaque;
129 type RustStringRepr = *mut RefCell<Vec<u8>>;
131 /// Appending to a Rust string -- used by RawRustStringOstream.
133 pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: RustStringRef,
136 let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
138 let sr = sr as RustStringRepr;
139 (*sr).borrow_mut().extend_from_slice(slice);
142 pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
144 LLVMSetInstructionCallConv(instr, cc as c_uint);
147 pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
149 LLVMSetFunctionCallConv(fn_, cc as c_uint);
153 // Externally visible symbols that might appear in multiple translation units need to appear in
154 // their own comdat section so that the duplicates can be discarded at link time. This can for
155 // example happen for generics when using multiple codegen units. This function simply uses the
156 // value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
158 // For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
159 pub fn SetUniqueComdat(llmod: ModuleRef, val: ValueRef) {
161 LLVMRustSetComdat(llmod, val, LLVMGetValueName(val));
165 pub fn UnsetComdat(val: ValueRef) {
167 LLVMRustUnsetComdat(val);
171 pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
173 LLVMSetUnnamedAddr(global, unnamed as Bool);
177 pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
179 LLVMSetThreadLocal(global, is_thread_local as Bool);
184 pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
185 unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) }
188 pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
189 unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) }
192 pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
193 unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) }
196 pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) {
198 self.apply_llfn(idx, llfn);
200 self.unapply_llfn(idx, llfn);
205 // Memory-managed interface to target data.
207 pub struct TargetData {
208 pub lltd: TargetDataRef,
211 impl Drop for TargetData {
214 LLVMDisposeTargetData(self.lltd);
219 pub fn mk_target_data(string_rep: &str) -> TargetData {
220 let string_rep = CString::new(string_rep).unwrap();
221 TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) } }
224 // Memory-managed interface to object files.
226 pub struct ObjectFile {
227 pub llof: ObjectFileRef,
231 // This will take ownership of llmb
232 pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
234 let llof = LLVMCreateObjectFile(llmb);
235 if llof as isize == 0 {
236 // LLVMCreateObjectFile took ownership of llmb
240 Some(ObjectFile { llof: llof })
245 impl Drop for ObjectFile {
248 LLVMDisposeObjectFile(self.llof);
253 // Memory-managed interface to section iterators.
255 pub struct SectionIter {
256 pub llsi: SectionIteratorRef,
259 impl Drop for SectionIter {
262 LLVMDisposeSectionIterator(self.llsi);
267 pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
268 unsafe { SectionIter { llsi: LLVMGetSections(llof) } }
271 /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
272 pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
274 assert!(index < LLVMCountParams(llfn),
275 "out of bounds argument access: {} out of {} arguments", index, LLVMCountParams(llfn));
276 LLVMGetParam(llfn, index)
280 pub fn get_params(llfn: ValueRef) -> Vec<ValueRef> {
282 let num_params = LLVMCountParams(llfn);
283 let mut params = Vec::with_capacity(num_params as usize);
284 for idx in 0..num_params {
285 params.push(LLVMGetParam(llfn, idx));
292 pub fn build_string<F>(f: F) -> Option<String>
293 where F: FnOnce(RustStringRef)
295 let mut buf = RefCell::new(Vec::new());
296 f(&mut buf as RustStringRepr as RustStringRef);
297 String::from_utf8(buf.into_inner()).ok()
300 pub unsafe fn twine_to_string(tr: TwineRef) -> String {
301 build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM")
304 pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
305 build_string(|s| LLVMRustWriteDebugLocToString(c, tr, s))
306 .expect("got a non-UTF8 DebugLoc from LLVM")
309 pub fn initialize_available_targets() {
310 macro_rules! init_target(
311 ($cfg:meta, $($method:ident),*) => { {
326 init_target!(llvm_component = "x86",
327 LLVMInitializeX86TargetInfo,
328 LLVMInitializeX86Target,
329 LLVMInitializeX86TargetMC,
330 LLVMInitializeX86AsmPrinter,
331 LLVMInitializeX86AsmParser);
332 init_target!(llvm_component = "arm",
333 LLVMInitializeARMTargetInfo,
334 LLVMInitializeARMTarget,
335 LLVMInitializeARMTargetMC,
336 LLVMInitializeARMAsmPrinter,
337 LLVMInitializeARMAsmParser);
338 init_target!(llvm_component = "aarch64",
339 LLVMInitializeAArch64TargetInfo,
340 LLVMInitializeAArch64Target,
341 LLVMInitializeAArch64TargetMC,
342 LLVMInitializeAArch64AsmPrinter,
343 LLVMInitializeAArch64AsmParser);
344 init_target!(llvm_component = "mips",
345 LLVMInitializeMipsTargetInfo,
346 LLVMInitializeMipsTarget,
347 LLVMInitializeMipsTargetMC,
348 LLVMInitializeMipsAsmPrinter,
349 LLVMInitializeMipsAsmParser);
350 init_target!(llvm_component = "powerpc",
351 LLVMInitializePowerPCTargetInfo,
352 LLVMInitializePowerPCTarget,
353 LLVMInitializePowerPCTargetMC,
354 LLVMInitializePowerPCAsmPrinter,
355 LLVMInitializePowerPCAsmParser);
356 init_target!(llvm_component = "pnacl",
357 LLVMInitializePNaClTargetInfo,
358 LLVMInitializePNaClTarget,
359 LLVMInitializePNaClTargetMC);
360 init_target!(llvm_component = "systemz",
361 LLVMInitializeSystemZTargetInfo,
362 LLVMInitializeSystemZTarget,
363 LLVMInitializeSystemZTargetMC,
364 LLVMInitializeSystemZAsmPrinter,
365 LLVMInitializeSystemZAsmParser);
366 init_target!(llvm_component = "jsbackend",
367 LLVMInitializeJSBackendTargetInfo,
368 LLVMInitializeJSBackendTarget,
369 LLVMInitializeJSBackendTargetMC);
370 init_target!(llvm_component = "msp430",
371 LLVMInitializeMSP430TargetInfo,
372 LLVMInitializeMSP430Target,
373 LLVMInitializeMSP430TargetMC,
374 LLVMInitializeMSP430AsmPrinter);
375 init_target!(llvm_component = "sparc",
376 LLVMInitializeSparcTargetInfo,
377 LLVMInitializeSparcTarget,
378 LLVMInitializeSparcTargetMC,
379 LLVMInitializeSparcAsmPrinter,
380 LLVMInitializeSparcAsmParser);
381 init_target!(llvm_component = "nvptx",
382 LLVMInitializeNVPTXTargetInfo,
383 LLVMInitializeNVPTXTarget,
384 LLVMInitializeNVPTXTargetMC,
385 LLVMInitializeNVPTXAsmPrinter);
386 init_target!(llvm_component = "hexagon",
387 LLVMInitializeHexagonTargetInfo,
388 LLVMInitializeHexagonTarget,
389 LLVMInitializeHexagonTargetMC,
390 LLVMInitializeHexagonAsmPrinter,
391 LLVMInitializeHexagonAsmParser);
394 pub fn last_error() -> Option<String> {
396 let cstr = LLVMRustGetLastError();
400 let err = CStr::from_ptr(cstr).to_bytes();
401 let err = String::from_utf8_lossy(err).to_string();
402 libc::free(cstr as *mut _);
408 pub struct OperandBundleDef {
409 inner: OperandBundleDefRef,
412 impl OperandBundleDef {
413 pub fn new(name: &str, vals: &[ValueRef]) -> OperandBundleDef {
414 let name = CString::new(name).unwrap();
416 LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
418 OperandBundleDef { inner: def }
421 pub fn raw(&self) -> OperandBundleDefRef {
426 impl Drop for OperandBundleDef {
429 LLVMRustFreeOperandBundleDef(self.inner);