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 #![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))]
25 #![feature(associated_consts)]
26 #![feature(box_syntax)]
28 #![feature(link_args)]
29 #![feature(staged_api)]
30 #![feature(linked_from)]
31 #![feature(concat_idents)]
36 extern crate rustc_bitflags
;
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
::*;
49 use std
::str::FromStr
;
51 use std
::ffi
::{CString, CStr}
;
52 use std
::cell
::RefCell
;
53 use libc
::{c_uint, c_char, size_t}
;
62 pub fn into_result(self) -> Result
<(), ()> {
64 LLVMRustResult
::Success
=> Ok(()),
65 LLVMRustResult
::Failure
=> Err(()),
70 #[derive(Copy, Clone, Default, Debug)]
71 pub struct Attributes
{
73 dereferenceable_bytes
: u64,
77 pub fn set(&mut self, attr
: Attribute
) -> &mut Self {
78 self.regular
= self.regular
| attr
;
82 pub fn unset(&mut self, attr
: Attribute
) -> &mut Self {
83 self.regular
= self.regular
- attr
;
87 pub fn set_dereferenceable(&mut self, bytes
: u64) -> &mut Self {
88 self.dereferenceable_bytes
= bytes
;
92 pub fn unset_dereferenceable(&mut self) -> &mut Self {
93 self.dereferenceable_bytes
= 0;
97 pub fn apply_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
) {
99 self.regular
.apply_llfn(idx
, llfn
);
100 if self.dereferenceable_bytes
!= 0 {
101 LLVMRustAddDereferenceableAttr(llfn
, idx
.as_uint(), self.dereferenceable_bytes
);
106 pub fn apply_callsite(&self, idx
: AttributePlace
, callsite
: ValueRef
) {
108 self.regular
.apply_callsite(idx
, callsite
);
109 if self.dereferenceable_bytes
!= 0 {
110 LLVMRustAddDereferenceableCallSiteAttr(callsite
,
112 self.dereferenceable_bytes
);
118 pub fn AddFunctionAttrStringValue(llfn
: ValueRef
,
121 value
: &'
static str) {
123 LLVMRustAddFunctionAttrStringValue(llfn
,
125 attr
.as_ptr() as *const _
,
126 value
.as_ptr() as *const _
)
131 #[derive(Copy, Clone)]
132 pub enum AttributePlace
{
137 impl AttributePlace
{
138 pub fn ReturnValue() -> Self {
139 AttributePlace
::Argument(0)
142 fn as_uint(self) -> c_uint
{
144 AttributePlace
::Function
=> !0,
145 AttributePlace
::Argument(i
) => i
,
150 #[derive(Copy, Clone, PartialEq)]
152 pub enum CodeGenOptSize
{
153 CodeGenOptSizeNone
= 0,
154 CodeGenOptSizeDefault
= 1,
155 CodeGenOptSizeAggressive
= 2,
158 impl FromStr
for ArchiveKind
{
161 fn from_str(s
: &str) -> Result
<Self, Self::Err
> {
163 "gnu" => Ok(ArchiveKind
::K_GNU
),
164 "mips64" => Ok(ArchiveKind
::K_MIPS64
),
165 "bsd" => Ok(ArchiveKind
::K_BSD
),
166 "coff" => Ok(ArchiveKind
::K_COFF
),
172 #[allow(missing_copy_implementations)]
173 pub enum RustString_opaque {}
174 pub type RustStringRef
= *mut RustString_opaque
;
175 type RustStringRepr
= *mut RefCell
<Vec
<u8>>;
177 /// Appending to a Rust string -- used by raw_rust_string_ostream.
179 pub unsafe extern "C" fn rust_llvm_string_write_impl(sr
: RustStringRef
,
182 let slice
= slice
::from_raw_parts(ptr
as *const u8, size
as usize);
184 let sr
= sr
as RustStringRepr
;
185 (*sr
).borrow_mut().extend_from_slice(slice
);
188 pub fn SetInstructionCallConv(instr
: ValueRef
, cc
: CallConv
) {
190 LLVMSetInstructionCallConv(instr
, cc
as c_uint
);
193 pub fn SetFunctionCallConv(fn_
: ValueRef
, cc
: CallConv
) {
195 LLVMSetFunctionCallConv(fn_
, cc
as c_uint
);
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
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
) {
207 LLVMRustSetComdat(llmod
, val
, LLVMGetValueName(val
));
211 pub fn UnsetComdat(val
: ValueRef
) {
213 LLVMRustUnsetComdat(val
);
217 pub fn SetUnnamedAddr(global
: ValueRef
, unnamed
: bool
) {
219 LLVMSetUnnamedAddr(global
, unnamed
as Bool
);
223 pub fn set_thread_local(global
: ValueRef
, is_thread_local
: bool
) {
225 LLVMSetThreadLocal(global
, is_thread_local
as Bool
);
230 pub fn apply_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
) {
231 unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), self.bits()) }
234 pub fn apply_callsite(&self, idx
: AttributePlace
, callsite
: ValueRef
) {
235 unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), self.bits()) }
238 pub fn unapply_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
) {
239 unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), self.bits()) }
242 pub fn toggle_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
, set
: bool
) {
244 self.apply_llfn(idx
, llfn
);
246 self.unapply_llfn(idx
, llfn
);
251 // Memory-managed interface to target data.
253 pub struct TargetData
{
254 pub lltd
: TargetDataRef
,
257 impl Drop
for TargetData
{
260 LLVMDisposeTargetData(self.lltd
);
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()) }
}
270 // Memory-managed interface to object files.
272 pub struct ObjectFile
{
273 pub llof
: ObjectFileRef
,
277 // This will take ownership of llmb
278 pub fn new(llmb
: MemoryBufferRef
) -> Option
<ObjectFile
> {
280 let llof
= LLVMCreateObjectFile(llmb
);
281 if llof
as isize == 0 {
282 // LLVMCreateObjectFile took ownership of llmb
286 Some(ObjectFile { llof: llof }
)
291 impl Drop
for ObjectFile
{
294 LLVMDisposeObjectFile(self.llof
);
299 // Memory-managed interface to section iterators.
301 pub struct SectionIter
{
302 pub llsi
: SectionIteratorRef
,
305 impl Drop
for SectionIter
{
308 LLVMDisposeSectionIterator(self.llsi
);
313 pub fn mk_section_iter(llof
: ObjectFileRef
) -> SectionIter
{
314 unsafe { SectionIter { llsi: LLVMGetSections(llof) }
}
317 /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
318 pub fn get_param(llfn
: ValueRef
, index
: c_uint
) -> ValueRef
{
320 assert
!(index
< LLVMCountParams(llfn
));
321 LLVMGetParam(llfn
, index
)
325 pub fn get_params(llfn
: ValueRef
) -> Vec
<ValueRef
> {
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
));
337 pub fn build_string
<F
>(f
: F
) -> Option
<String
>
338 where F
: FnOnce(RustStringRef
)
340 let mut buf
= RefCell
::new(Vec
::new());
341 f(&mut buf
as RustStringRepr
as RustStringRef
);
342 String
::from_utf8(buf
.into_inner()).ok()
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")
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")
354 pub fn initialize_available_targets() {
355 macro_rules
! init_target(
356 ($cfg
:meta
, $
($method
:ident
),*) => { {
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
);
417 pub fn last_error() -> Option
<String
> {
419 let cstr
= LLVMRustGetLastError();
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 _
);
431 pub struct OperandBundleDef
{
432 inner
: OperandBundleDefRef
,
435 impl OperandBundleDef
{
436 pub fn new(name
: &str, vals
: &[ValueRef
]) -> OperandBundleDef
{
437 let name
= CString
::new(name
).unwrap();
439 LLVMRustBuildOperandBundleDef(name
.as_ptr(), vals
.as_ptr(), vals
.len() as c_uint
)
441 OperandBundleDef { inner: def }
444 pub fn raw(&self) -> OperandBundleDefRef
{
449 impl Drop
for OperandBundleDef
{
452 LLVMRustFreeOperandBundleDef(self.inner
);
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))]
464 include
! { env!("CFG_LLVM_LINKAGE_FILE") }