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/")]
21 #![feature(box_syntax)]
22 #![feature(concat_idents)]
24 #![feature(link_args)]
25 #![feature(static_nobundle)]
27 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
28 #[allow(unused_extern_crates)]
29 extern crate rustc_cratesio_shim
;
32 extern crate bitflags
;
35 pub use self::IntPredicate
::*;
36 pub use self::RealPredicate
::*;
37 pub use self::TypeKind
::*;
38 pub use self::AtomicRmwBinOp
::*;
39 pub use self::MetadataType
::*;
40 pub use self::CodeGenOptSize
::*;
41 pub use self::CallConv
::*;
42 pub use self::Linkage
::*;
44 use std
::str::FromStr
;
46 use std
::ffi
::{CString, CStr}
;
47 use std
::cell
::RefCell
;
48 use libc
::{c_uint, c_char, size_t}
;
57 pub fn into_result(self) -> Result
<(), ()> {
59 LLVMRustResult
::Success
=> Ok(()),
60 LLVMRustResult
::Failure
=> Err(()),
65 pub fn AddFunctionAttrStringValue(llfn
: ValueRef
,
70 LLVMRustAddFunctionAttrStringValue(llfn
,
77 #[derive(Copy, Clone)]
78 pub enum AttributePlace
{
85 pub fn as_uint(self) -> c_uint
{
87 AttributePlace
::ReturnValue
=> 0,
88 AttributePlace
::Argument(i
) => 1 + i
,
89 AttributePlace
::Function
=> !0,
94 #[derive(Copy, Clone, PartialEq)]
96 pub enum CodeGenOptSize
{
97 CodeGenOptSizeNone
= 0,
98 CodeGenOptSizeDefault
= 1,
99 CodeGenOptSizeAggressive
= 2,
102 impl FromStr
for ArchiveKind
{
105 fn from_str(s
: &str) -> Result
<Self, Self::Err
> {
107 "gnu" => Ok(ArchiveKind
::K_GNU
),
108 "bsd" => Ok(ArchiveKind
::K_BSD
),
109 "coff" => Ok(ArchiveKind
::K_COFF
),
115 #[allow(missing_copy_implementations)]
116 pub enum RustString_opaque {}
117 type RustStringRef
= *mut RustString_opaque
;
118 type RustStringRepr
= *mut RefCell
<Vec
<u8>>;
120 /// Appending to a Rust string -- used by RawRustStringOstream.
122 pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr
: RustStringRef
,
125 let slice
= slice
::from_raw_parts(ptr
as *const u8, size
as usize);
127 let sr
= sr
as RustStringRepr
;
128 (*sr
).borrow_mut().extend_from_slice(slice
);
131 pub fn SetInstructionCallConv(instr
: ValueRef
, cc
: CallConv
) {
133 LLVMSetInstructionCallConv(instr
, cc
as c_uint
);
136 pub fn SetFunctionCallConv(fn_
: ValueRef
, cc
: CallConv
) {
138 LLVMSetFunctionCallConv(fn_
, cc
as c_uint
);
142 // Externally visible symbols that might appear in multiple translation units need to appear in
143 // their own comdat section so that the duplicates can be discarded at link time. This can for
144 // example happen for generics when using multiple codegen units. This function simply uses the
145 // value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
147 // For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
148 pub fn SetUniqueComdat(llmod
: ModuleRef
, val
: ValueRef
) {
150 LLVMRustSetComdat(llmod
, val
, LLVMGetValueName(val
));
154 pub fn UnsetComdat(val
: ValueRef
) {
156 LLVMRustUnsetComdat(val
);
160 pub fn SetUnnamedAddr(global
: ValueRef
, unnamed
: bool
) {
162 LLVMSetUnnamedAddr(global
, unnamed
as Bool
);
166 pub fn set_thread_local(global
: ValueRef
, is_thread_local
: bool
) {
168 LLVMSetThreadLocal(global
, is_thread_local
as Bool
);
171 pub fn set_thread_local_mode(global
: ValueRef
, mode
: ThreadLocalMode
) {
173 LLVMSetThreadLocalMode(global
, mode
);
178 pub fn apply_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
) {
179 unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) }
182 pub fn apply_callsite(&self, idx
: AttributePlace
, callsite
: ValueRef
) {
183 unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) }
186 pub fn unapply_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
) {
187 unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) }
190 pub fn toggle_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
, set
: bool
) {
192 self.apply_llfn(idx
, llfn
);
194 self.unapply_llfn(idx
, llfn
);
199 // Memory-managed interface to target data.
205 impl Drop
for TargetData
{
208 LLVMDisposeTargetData(self.lltd
);
213 fn mk_target_data(string_rep
: &str) -> TargetData
{
214 let string_rep
= CString
::new(string_rep
).unwrap();
215 TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) }
}
218 // Memory-managed interface to object files.
220 pub struct ObjectFile
{
221 pub llof
: ObjectFileRef
,
225 // This will take ownership of llmb
226 pub fn new(llmb
: MemoryBufferRef
) -> Option
<ObjectFile
> {
228 let llof
= LLVMCreateObjectFile(llmb
);
229 if llof
as isize == 0 {
230 // LLVMCreateObjectFile took ownership of llmb
234 Some(ObjectFile { llof: llof }
)
239 impl Drop
for ObjectFile
{
242 LLVMDisposeObjectFile(self.llof
);
247 // Memory-managed interface to section iterators.
249 pub struct SectionIter
{
250 pub llsi
: SectionIteratorRef
,
253 impl Drop
for SectionIter
{
256 LLVMDisposeSectionIterator(self.llsi
);
261 pub fn mk_section_iter(llof
: ObjectFileRef
) -> SectionIter
{
262 unsafe { SectionIter { llsi: LLVMGetSections(llof) }
}
265 /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
266 pub fn get_param(llfn
: ValueRef
, index
: c_uint
) -> ValueRef
{
268 assert
!(index
< LLVMCountParams(llfn
),
269 "out of bounds argument access: {} out of {} arguments", index
, LLVMCountParams(llfn
));
270 LLVMGetParam(llfn
, index
)
274 fn get_params(llfn
: ValueRef
) -> Vec
<ValueRef
> {
276 let num_params
= LLVMCountParams(llfn
);
277 let mut params
= Vec
::with_capacity(num_params
as usize);
278 for idx
in 0..num_params
{
279 params
.push(LLVMGetParam(llfn
, idx
));
286 pub fn build_string
<F
>(f
: F
) -> Option
<String
>
287 where F
: FnOnce(RustStringRef
)
289 let mut buf
= RefCell
::new(Vec
::new());
290 f(&mut buf
as RustStringRepr
as RustStringRef
);
291 String
::from_utf8(buf
.into_inner()).ok()
294 pub unsafe fn twine_to_string(tr
: TwineRef
) -> String
{
295 build_string(|s
| LLVMRustWriteTwineToString(tr
, s
)).expect("got a non-UTF8 Twine from LLVM")
298 pub fn initialize_available_targets() {
299 macro_rules
! init_target(
300 ($cfg
:meta
, $
($method
:ident
),*) => { {
315 init_target
!(llvm_component
= "x86",
316 LLVMInitializeX86TargetInfo
,
317 LLVMInitializeX86Target
,
318 LLVMInitializeX86TargetMC
,
319 LLVMInitializeX86AsmPrinter
,
320 LLVMInitializeX86AsmParser
);
321 init_target
!(llvm_component
= "arm",
322 LLVMInitializeARMTargetInfo
,
323 LLVMInitializeARMTarget
,
324 LLVMInitializeARMTargetMC
,
325 LLVMInitializeARMAsmPrinter
,
326 LLVMInitializeARMAsmParser
);
327 init_target
!(llvm_component
= "aarch64",
328 LLVMInitializeAArch64TargetInfo
,
329 LLVMInitializeAArch64Target
,
330 LLVMInitializeAArch64TargetMC
,
331 LLVMInitializeAArch64AsmPrinter
,
332 LLVMInitializeAArch64AsmParser
);
333 init_target
!(llvm_component
= "mips",
334 LLVMInitializeMipsTargetInfo
,
335 LLVMInitializeMipsTarget
,
336 LLVMInitializeMipsTargetMC
,
337 LLVMInitializeMipsAsmPrinter
,
338 LLVMInitializeMipsAsmParser
);
339 init_target
!(llvm_component
= "powerpc",
340 LLVMInitializePowerPCTargetInfo
,
341 LLVMInitializePowerPCTarget
,
342 LLVMInitializePowerPCTargetMC
,
343 LLVMInitializePowerPCAsmPrinter
,
344 LLVMInitializePowerPCAsmParser
);
345 init_target
!(llvm_component
= "systemz",
346 LLVMInitializeSystemZTargetInfo
,
347 LLVMInitializeSystemZTarget
,
348 LLVMInitializeSystemZTargetMC
,
349 LLVMInitializeSystemZAsmPrinter
,
350 LLVMInitializeSystemZAsmParser
);
351 init_target
!(llvm_component
= "jsbackend",
352 LLVMInitializeJSBackendTargetInfo
,
353 LLVMInitializeJSBackendTarget
,
354 LLVMInitializeJSBackendTargetMC
);
355 init_target
!(llvm_component
= "msp430",
356 LLVMInitializeMSP430TargetInfo
,
357 LLVMInitializeMSP430Target
,
358 LLVMInitializeMSP430TargetMC
,
359 LLVMInitializeMSP430AsmPrinter
);
360 init_target
!(llvm_component
= "sparc",
361 LLVMInitializeSparcTargetInfo
,
362 LLVMInitializeSparcTarget
,
363 LLVMInitializeSparcTargetMC
,
364 LLVMInitializeSparcAsmPrinter
,
365 LLVMInitializeSparcAsmParser
);
366 init_target
!(llvm_component
= "nvptx",
367 LLVMInitializeNVPTXTargetInfo
,
368 LLVMInitializeNVPTXTarget
,
369 LLVMInitializeNVPTXTargetMC
,
370 LLVMInitializeNVPTXAsmPrinter
);
371 init_target
!(llvm_component
= "hexagon",
372 LLVMInitializeHexagonTargetInfo
,
373 LLVMInitializeHexagonTarget
,
374 LLVMInitializeHexagonTargetMC
,
375 LLVMInitializeHexagonAsmPrinter
,
376 LLVMInitializeHexagonAsmParser
);
377 init_target
!(llvm_component
= "webassembly",
378 LLVMInitializeWebAssemblyTargetInfo
,
379 LLVMInitializeWebAssemblyTarget
,
380 LLVMInitializeWebAssemblyTargetMC
,
381 LLVMInitializeWebAssemblyAsmPrinter
);
384 pub fn last_error() -> Option
<String
> {
386 let cstr
= LLVMRustGetLastError();
390 let err
= CStr
::from_ptr(cstr
).to_bytes();
391 let err
= String
::from_utf8_lossy(err
).to_string();
392 libc
::free(cstr
as *mut _
);
398 pub struct OperandBundleDef
{
399 inner
: OperandBundleDefRef
,
402 impl OperandBundleDef
{
403 pub fn new(name
: &str, vals
: &[ValueRef
]) -> OperandBundleDef
{
404 let name
= CString
::new(name
).unwrap();
406 LLVMRustBuildOperandBundleDef(name
.as_ptr(), vals
.as_ptr(), vals
.len() as c_uint
)
408 OperandBundleDef { inner: def }
411 pub fn raw(&self) -> OperandBundleDefRef
{
416 impl Drop
for OperandBundleDef
{
419 LLVMRustFreeOperandBundleDef(self.inner
);