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
,
78 #[derive(Copy, Clone)]
79 pub enum AttributePlace
{
85 pub fn ReturnValue() -> Self {
86 AttributePlace
::Argument(0)
89 pub fn as_uint(self) -> c_uint
{
91 AttributePlace
::Function
=> !0,
92 AttributePlace
::Argument(i
) => i
,
97 #[derive(Copy, Clone, PartialEq)]
99 pub enum CodeGenOptSize
{
100 CodeGenOptSizeNone
= 0,
101 CodeGenOptSizeDefault
= 1,
102 CodeGenOptSizeAggressive
= 2,
105 impl FromStr
for ArchiveKind
{
108 fn from_str(s
: &str) -> Result
<Self, Self::Err
> {
110 "gnu" => Ok(ArchiveKind
::K_GNU
),
111 "mips64" => Ok(ArchiveKind
::K_MIPS64
),
112 "bsd" => Ok(ArchiveKind
::K_BSD
),
113 "coff" => Ok(ArchiveKind
::K_COFF
),
119 #[allow(missing_copy_implementations)]
120 pub enum RustString_opaque {}
121 type RustStringRef
= *mut RustString_opaque
;
122 type RustStringRepr
= *mut RefCell
<Vec
<u8>>;
124 /// Appending to a Rust string -- used by RawRustStringOstream.
126 pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr
: RustStringRef
,
129 let slice
= slice
::from_raw_parts(ptr
as *const u8, size
as usize);
131 let sr
= sr
as RustStringRepr
;
132 (*sr
).borrow_mut().extend_from_slice(slice
);
135 pub fn SetInstructionCallConv(instr
: ValueRef
, cc
: CallConv
) {
137 LLVMSetInstructionCallConv(instr
, cc
as c_uint
);
140 pub fn SetFunctionCallConv(fn_
: ValueRef
, cc
: CallConv
) {
142 LLVMSetFunctionCallConv(fn_
, cc
as c_uint
);
146 // Externally visible symbols that might appear in multiple translation units need to appear in
147 // their own comdat section so that the duplicates can be discarded at link time. This can for
148 // example happen for generics when using multiple codegen units. This function simply uses the
149 // value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
151 // For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
152 pub fn SetUniqueComdat(llmod
: ModuleRef
, val
: ValueRef
) {
154 LLVMRustSetComdat(llmod
, val
, LLVMGetValueName(val
));
158 pub fn UnsetComdat(val
: ValueRef
) {
160 LLVMRustUnsetComdat(val
);
164 pub fn SetUnnamedAddr(global
: ValueRef
, unnamed
: bool
) {
166 LLVMSetUnnamedAddr(global
, unnamed
as Bool
);
170 pub fn set_thread_local(global
: ValueRef
, is_thread_local
: bool
) {
172 LLVMSetThreadLocal(global
, is_thread_local
as Bool
);
175 pub fn set_thread_local_mode(global
: ValueRef
, mode
: ThreadLocalMode
) {
177 LLVMSetThreadLocalMode(global
, mode
);
182 pub fn apply_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
) {
183 unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) }
186 pub fn apply_callsite(&self, idx
: AttributePlace
, callsite
: ValueRef
) {
187 unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) }
190 pub fn unapply_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
) {
191 unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) }
194 pub fn toggle_llfn(&self, idx
: AttributePlace
, llfn
: ValueRef
, set
: bool
) {
196 self.apply_llfn(idx
, llfn
);
198 self.unapply_llfn(idx
, llfn
);
203 // Memory-managed interface to target data.
209 impl Drop
for TargetData
{
212 LLVMDisposeTargetData(self.lltd
);
217 fn mk_target_data(string_rep
: &str) -> TargetData
{
218 let string_rep
= CString
::new(string_rep
).unwrap();
219 TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) }
}
222 // Memory-managed interface to object files.
224 pub struct ObjectFile
{
225 pub llof
: ObjectFileRef
,
229 // This will take ownership of llmb
230 pub fn new(llmb
: MemoryBufferRef
) -> Option
<ObjectFile
> {
232 let llof
= LLVMCreateObjectFile(llmb
);
233 if llof
as isize == 0 {
234 // LLVMCreateObjectFile took ownership of llmb
238 Some(ObjectFile { llof: llof }
)
243 impl Drop
for ObjectFile
{
246 LLVMDisposeObjectFile(self.llof
);
251 // Memory-managed interface to section iterators.
253 pub struct SectionIter
{
254 pub llsi
: SectionIteratorRef
,
257 impl Drop
for SectionIter
{
260 LLVMDisposeSectionIterator(self.llsi
);
265 pub fn mk_section_iter(llof
: ObjectFileRef
) -> SectionIter
{
266 unsafe { SectionIter { llsi: LLVMGetSections(llof) }
}
269 /// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
270 pub fn get_param(llfn
: ValueRef
, index
: c_uint
) -> ValueRef
{
272 assert
!(index
< LLVMCountParams(llfn
),
273 "out of bounds argument access: {} out of {} arguments", index
, LLVMCountParams(llfn
));
274 LLVMGetParam(llfn
, index
)
278 fn get_params(llfn
: ValueRef
) -> Vec
<ValueRef
> {
280 let num_params
= LLVMCountParams(llfn
);
281 let mut params
= Vec
::with_capacity(num_params
as usize);
282 for idx
in 0..num_params
{
283 params
.push(LLVMGetParam(llfn
, idx
));
290 pub fn build_string
<F
>(f
: F
) -> Option
<String
>
291 where F
: FnOnce(RustStringRef
)
293 let mut buf
= RefCell
::new(Vec
::new());
294 f(&mut buf
as RustStringRepr
as RustStringRef
);
295 String
::from_utf8(buf
.into_inner()).ok()
298 pub unsafe fn twine_to_string(tr
: TwineRef
) -> String
{
299 build_string(|s
| LLVMRustWriteTwineToString(tr
, s
)).expect("got a non-UTF8 Twine from LLVM")
302 pub unsafe fn debug_loc_to_string(c
: ContextRef
, tr
: DebugLocRef
) -> String
{
303 build_string(|s
| LLVMRustWriteDebugLocToString(c
, tr
, s
))
304 .expect("got a non-UTF8 DebugLoc from LLVM")
307 pub fn initialize_available_targets() {
308 macro_rules
! init_target(
309 ($cfg
:meta
, $
($method
:ident
),*) => { {
324 init_target
!(llvm_component
= "x86",
325 LLVMInitializeX86TargetInfo
,
326 LLVMInitializeX86Target
,
327 LLVMInitializeX86TargetMC
,
328 LLVMInitializeX86AsmPrinter
,
329 LLVMInitializeX86AsmParser
);
330 init_target
!(llvm_component
= "arm",
331 LLVMInitializeARMTargetInfo
,
332 LLVMInitializeARMTarget
,
333 LLVMInitializeARMTargetMC
,
334 LLVMInitializeARMAsmPrinter
,
335 LLVMInitializeARMAsmParser
);
336 init_target
!(llvm_component
= "aarch64",
337 LLVMInitializeAArch64TargetInfo
,
338 LLVMInitializeAArch64Target
,
339 LLVMInitializeAArch64TargetMC
,
340 LLVMInitializeAArch64AsmPrinter
,
341 LLVMInitializeAArch64AsmParser
);
342 init_target
!(llvm_component
= "mips",
343 LLVMInitializeMipsTargetInfo
,
344 LLVMInitializeMipsTarget
,
345 LLVMInitializeMipsTargetMC
,
346 LLVMInitializeMipsAsmPrinter
,
347 LLVMInitializeMipsAsmParser
);
348 init_target
!(llvm_component
= "powerpc",
349 LLVMInitializePowerPCTargetInfo
,
350 LLVMInitializePowerPCTarget
,
351 LLVMInitializePowerPCTargetMC
,
352 LLVMInitializePowerPCAsmPrinter
,
353 LLVMInitializePowerPCAsmParser
);
354 init_target
!(llvm_component
= "systemz",
355 LLVMInitializeSystemZTargetInfo
,
356 LLVMInitializeSystemZTarget
,
357 LLVMInitializeSystemZTargetMC
,
358 LLVMInitializeSystemZAsmPrinter
,
359 LLVMInitializeSystemZAsmParser
);
360 init_target
!(llvm_component
= "jsbackend",
361 LLVMInitializeJSBackendTargetInfo
,
362 LLVMInitializeJSBackendTarget
,
363 LLVMInitializeJSBackendTargetMC
);
364 init_target
!(llvm_component
= "msp430",
365 LLVMInitializeMSP430TargetInfo
,
366 LLVMInitializeMSP430Target
,
367 LLVMInitializeMSP430TargetMC
,
368 LLVMInitializeMSP430AsmPrinter
);
369 init_target
!(llvm_component
= "sparc",
370 LLVMInitializeSparcTargetInfo
,
371 LLVMInitializeSparcTarget
,
372 LLVMInitializeSparcTargetMC
,
373 LLVMInitializeSparcAsmPrinter
,
374 LLVMInitializeSparcAsmParser
);
375 init_target
!(llvm_component
= "nvptx",
376 LLVMInitializeNVPTXTargetInfo
,
377 LLVMInitializeNVPTXTarget
,
378 LLVMInitializeNVPTXTargetMC
,
379 LLVMInitializeNVPTXAsmPrinter
);
380 init_target
!(llvm_component
= "hexagon",
381 LLVMInitializeHexagonTargetInfo
,
382 LLVMInitializeHexagonTarget
,
383 LLVMInitializeHexagonTargetMC
,
384 LLVMInitializeHexagonAsmPrinter
,
385 LLVMInitializeHexagonAsmParser
);
386 init_target
!(llvm_component
= "webassembly",
387 LLVMInitializeWebAssemblyTargetInfo
,
388 LLVMInitializeWebAssemblyTarget
,
389 LLVMInitializeWebAssemblyTargetMC
,
390 LLVMInitializeWebAssemblyAsmPrinter
);
393 pub fn last_error() -> Option
<String
> {
395 let cstr
= LLVMRustGetLastError();
399 let err
= CStr
::from_ptr(cstr
).to_bytes();
400 let err
= String
::from_utf8_lossy(err
).to_string();
401 libc
::free(cstr
as *mut _
);
407 pub struct OperandBundleDef
{
408 inner
: OperandBundleDefRef
,
411 impl OperandBundleDef
{
412 pub fn new(name
: &str, vals
: &[ValueRef
]) -> OperandBundleDef
{
413 let name
= CString
::new(name
).unwrap();
415 LLVMRustBuildOperandBundleDef(name
.as_ptr(), vals
.as_ptr(), vals
.len() as c_uint
)
417 OperandBundleDef { inner: def }
420 pub fn raw(&self) -> OperandBundleDefRef
{
425 impl Drop
for OperandBundleDef
{
428 LLVMRustFreeOperandBundleDef(self.inner
);