2014-12-12 23:39:27 +00:00
|
|
|
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 16:48:01 -08:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2014-10-27 15:37:07 -07:00
|
|
|
#![allow(non_upper_case_globals)]
|
2014-03-21 18:05:05 -07:00
|
|
|
#![allow(non_camel_case_types)]
|
2014-07-19 00:45:17 +12:00
|
|
|
#![allow(non_snake_case)]
|
2014-04-01 10:17:18 -04:00
|
|
|
#![allow(dead_code)]
|
2013-08-14 21:41:40 -04:00
|
|
|
|
2015-08-09 14:15:05 -07:00
|
|
|
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
2015-05-15 16:04:01 -07:00
|
|
|
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
2015-08-09 14:15:05 -07:00
|
|
|
html_root_url = "https://doc.rust-lang.org/nightly/")]
|
2016-12-29 09:47:34 -08:00
|
|
|
#![deny(warnings)]
|
2014-07-05 13:24:57 -07:00
|
|
|
|
2015-01-08 01:03:46 +01:00
|
|
|
#![feature(box_syntax)]
|
2016-11-16 09:19:02 -08:00
|
|
|
#![feature(concat_idents)]
|
2015-01-22 18:22:03 -08:00
|
|
|
#![feature(libc)]
|
2015-01-30 12:26:44 -08:00
|
|
|
#![feature(link_args)]
|
2017-04-13 22:27:53 +02:00
|
|
|
#![feature(static_nobundle)]
|
2014-07-05 13:24:57 -07:00
|
|
|
|
|
|
|
extern crate libc;
|
2016-11-18 17:15:14 -05:00
|
|
|
#[macro_use]
|
|
|
|
#[no_link]
|
|
|
|
extern crate rustc_bitflags;
|
2011-05-12 17:24:54 +02:00
|
|
|
|
2014-11-06 00:05:53 -08:00
|
|
|
pub use self::IntPredicate::*;
|
|
|
|
pub use self::RealPredicate::*;
|
|
|
|
pub use self::TypeKind::*;
|
2016-08-02 23:10:10 +03:00
|
|
|
pub use self::AtomicRmwBinOp::*;
|
2014-11-06 00:05:53 -08:00
|
|
|
pub use self::MetadataType::*;
|
2016-03-27 12:42:47 -07:00
|
|
|
pub use self::CodeGenOptSize::*;
|
2014-11-06 00:05:53 -08:00
|
|
|
pub use self::CallConv::*;
|
2014-11-25 10:00:46 -08:00
|
|
|
pub use self::Linkage::*;
|
2014-11-06 00:05:53 -08:00
|
|
|
|
2016-06-10 17:27:19 -04:00
|
|
|
use std::str::FromStr;
|
2016-08-02 23:10:10 +03:00
|
|
|
use std::slice;
|
2015-10-22 22:07:19 -07:00
|
|
|
use std::ffi::{CString, CStr};
|
2014-09-09 23:12:09 -07:00
|
|
|
use std::cell::RefCell;
|
2016-08-03 00:25:19 +03:00
|
|
|
use libc::{c_uint, c_char, size_t};
|
2013-06-15 22:16:47 +12:00
|
|
|
|
2014-07-06 21:43:22 -07:00
|
|
|
pub mod archive_ro;
|
2014-09-12 08:17:58 -07:00
|
|
|
pub mod diagnostic;
|
2017-08-19 03:09:55 +03:00
|
|
|
mod ffi;
|
2014-07-06 21:43:22 -07:00
|
|
|
|
2016-08-02 23:10:10 +03:00
|
|
|
pub use ffi::*;
|
2016-08-02 00:16:16 +03:00
|
|
|
|
|
|
|
impl LLVMRustResult {
|
|
|
|
pub fn into_result(self) -> Result<(), ()> {
|
|
|
|
match self {
|
|
|
|
LLVMRustResult::Success => Ok(()),
|
|
|
|
LLVMRustResult::Failure => Err(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-22 18:37:35 +05:30
|
|
|
pub fn AddFunctionAttrStringValue(llfn: ValueRef,
|
|
|
|
idx: AttributePlace,
|
2016-11-29 19:02:00 -05:00
|
|
|
attr: &CStr,
|
|
|
|
value: &CStr) {
|
2016-08-03 00:25:19 +03:00
|
|
|
unsafe {
|
2016-10-22 18:37:35 +05:30
|
|
|
LLVMRustAddFunctionAttrStringValue(llfn,
|
|
|
|
idx.as_uint(),
|
2016-11-29 19:02:00 -05:00
|
|
|
attr.as_ptr(),
|
|
|
|
value.as_ptr())
|
2016-08-03 00:25:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-25 19:08:10 +02:00
|
|
|
#[repr(C)]
|
|
|
|
#[derive(Copy, Clone)]
|
2016-08-03 00:25:19 +03:00
|
|
|
pub enum AttributePlace {
|
|
|
|
Argument(u32),
|
|
|
|
Function,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AttributePlace {
|
|
|
|
pub fn ReturnValue() -> Self {
|
|
|
|
AttributePlace::Argument(0)
|
|
|
|
}
|
|
|
|
|
2016-11-16 23:36:08 +01:00
|
|
|
pub fn as_uint(self) -> c_uint {
|
2016-08-03 00:25:19 +03:00
|
|
|
match self {
|
|
|
|
AttributePlace::Function => !0,
|
|
|
|
AttributePlace::Argument(i) => i,
|
|
|
|
}
|
|
|
|
}
|
2016-02-25 19:08:10 +02:00
|
|
|
}
|
|
|
|
|
2016-03-27 12:42:47 -07:00
|
|
|
#[derive(Copy, Clone, PartialEq)]
|
|
|
|
#[repr(C)]
|
|
|
|
pub enum CodeGenOptSize {
|
|
|
|
CodeGenOptSizeNone = 0,
|
|
|
|
CodeGenOptSizeDefault = 1,
|
|
|
|
CodeGenOptSizeAggressive = 2,
|
|
|
|
}
|
|
|
|
|
2016-06-10 17:27:19 -04:00
|
|
|
impl FromStr for ArchiveKind {
|
|
|
|
type Err = ();
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
match s {
|
|
|
|
"gnu" => Ok(ArchiveKind::K_GNU),
|
|
|
|
"mips64" => Ok(ArchiveKind::K_MIPS64),
|
|
|
|
"bsd" => Ok(ArchiveKind::K_BSD),
|
|
|
|
"coff" => Ok(ArchiveKind::K_COFF),
|
|
|
|
_ => Err(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-16 20:03:44 +01:00
|
|
|
#[allow(missing_copy_implementations)]
|
2016-08-02 23:10:10 +03:00
|
|
|
pub enum RustString_opaque {}
|
2017-08-19 03:09:55 +03:00
|
|
|
type RustStringRef = *mut RustString_opaque;
|
2016-08-02 23:10:10 +03:00
|
|
|
type RustStringRepr = *mut RefCell<Vec<u8>>;
|
2016-02-04 19:40:28 +02:00
|
|
|
|
2016-12-31 12:01:23 -05:00
|
|
|
/// Appending to a Rust string -- used by RawRustStringOstream.
|
2016-08-02 23:10:10 +03:00
|
|
|
#[no_mangle]
|
2016-12-31 12:01:23 -05:00
|
|
|
pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: RustStringRef,
|
|
|
|
ptr: *const c_char,
|
|
|
|
size: size_t) {
|
2016-08-02 23:10:10 +03:00
|
|
|
let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
|
2016-03-28 17:57:31 +02:00
|
|
|
|
2016-08-02 23:10:10 +03:00
|
|
|
let sr = sr as RustStringRepr;
|
|
|
|
(*sr).borrow_mut().extend_from_slice(slice);
|
2013-07-02 18:10:24 +02:00
|
|
|
}
|
2011-03-25 18:44:52 -07:00
|
|
|
|
2014-02-15 16:15:03 -05:00
|
|
|
pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
|
2013-01-10 21:23:07 -08:00
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
LLVMSetInstructionCallConv(instr, cc as c_uint);
|
2013-01-10 21:23:07 -08:00
|
|
|
}
|
2012-02-01 11:04:56 +01:00
|
|
|
}
|
2014-02-15 16:15:03 -05:00
|
|
|
pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
|
2013-01-10 21:23:07 -08:00
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
LLVMSetFunctionCallConv(fn_, cc as c_uint);
|
2013-01-10 21:23:07 -08:00
|
|
|
}
|
2012-02-01 11:04:56 +01:00
|
|
|
}
|
|
|
|
|
2016-03-28 17:57:31 +02:00
|
|
|
// Externally visible symbols that might appear in multiple translation units need to appear in
|
|
|
|
// their own comdat section so that the duplicates can be discarded at link time. This can for
|
|
|
|
// example happen for generics when using multiple codegen units. This function simply uses the
|
|
|
|
// value's name as the comdat value to make sure that it is in a 1-to-1 relationship to the
|
|
|
|
// function.
|
|
|
|
// For more details on COMDAT sections see e.g. http://www.airs.com/blog/archives/52
|
|
|
|
pub fn SetUniqueComdat(llmod: ModuleRef, val: ValueRef) {
|
|
|
|
unsafe {
|
|
|
|
LLVMRustSetComdat(llmod, val, LLVMGetValueName(val));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn UnsetComdat(val: ValueRef) {
|
|
|
|
unsafe {
|
|
|
|
LLVMRustUnsetComdat(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-15 16:15:03 -05:00
|
|
|
pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
|
2013-08-09 13:47:00 -07:00
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
LLVMSetUnnamedAddr(global, unnamed as Bool);
|
2013-08-09 13:47:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-06 00:38:08 -05:00
|
|
|
pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
|
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
LLVMSetThreadLocal(global, is_thread_local as Bool);
|
2013-11-06 00:38:08 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-03 00:25:19 +03:00
|
|
|
impl Attribute {
|
|
|
|
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
|
2016-11-21 20:30:05 +09:00
|
|
|
unsafe { LLVMRustAddFunctionAttribute(llfn, idx.as_uint(), *self) }
|
2013-05-19 20:18:56 -04:00
|
|
|
}
|
2016-08-03 00:25:19 +03:00
|
|
|
|
|
|
|
pub fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
|
2016-11-21 20:30:05 +09:00
|
|
|
unsafe { LLVMRustAddCallSiteAttribute(callsite, idx.as_uint(), *self) }
|
2013-05-19 20:18:56 -04:00
|
|
|
}
|
2013-05-25 21:26:08 -05:00
|
|
|
|
2016-08-03 00:25:19 +03:00
|
|
|
pub fn unapply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
|
2016-11-21 20:30:05 +09:00
|
|
|
unsafe { LLVMRustRemoveFunctionAttributes(llfn, idx.as_uint(), *self) }
|
2013-08-02 00:55:49 -07:00
|
|
|
}
|
2014-07-05 13:24:57 -07:00
|
|
|
|
2016-10-22 18:37:35 +05:30
|
|
|
pub fn toggle_llfn(&self, idx: AttributePlace, llfn: ValueRef, set: bool) {
|
2016-08-03 00:25:19 +03:00
|
|
|
if set {
|
|
|
|
self.apply_llfn(idx, llfn);
|
|
|
|
} else {
|
|
|
|
self.unapply_llfn(idx, llfn);
|
|
|
|
}
|
2016-03-26 12:27:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-22 18:37:35 +05:30
|
|
|
// Memory-managed interface to target data.
|
2010-12-03 16:55:59 -08:00
|
|
|
|
2017-08-19 03:09:55 +03:00
|
|
|
struct TargetData {
|
|
|
|
lltd: TargetDataRef,
|
2013-02-27 19:13:53 -05:00
|
|
|
}
|
|
|
|
|
2014-04-22 03:53:51 +03:00
|
|
|
impl Drop for TargetData {
|
2013-09-16 21:18:07 -04:00
|
|
|
fn drop(&mut self) {
|
2013-01-10 21:23:07 -08:00
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
LLVMDisposeTargetData(self.lltd);
|
2013-01-10 21:23:07 -08:00
|
|
|
}
|
|
|
|
}
|
2010-12-03 16:55:59 -08:00
|
|
|
}
|
|
|
|
|
2017-08-19 03:09:55 +03:00
|
|
|
fn mk_target_data(string_rep: &str) -> TargetData {
|
2015-02-17 22:47:40 -08:00
|
|
|
let string_rep = CString::new(string_rep).unwrap();
|
2016-10-22 18:37:35 +05:30
|
|
|
TargetData { lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) } }
|
2010-12-03 16:55:59 -08:00
|
|
|
}
|
|
|
|
|
2016-10-22 18:37:35 +05:30
|
|
|
// Memory-managed interface to object files.
|
2011-03-15 12:27:15 -07:00
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
pub struct ObjectFile {
|
2014-03-28 10:05:27 -07:00
|
|
|
pub llof: ObjectFileRef,
|
2013-02-27 19:13:53 -05:00
|
|
|
}
|
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
impl ObjectFile {
|
|
|
|
// This will take ownership of llmb
|
|
|
|
pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
|
2013-01-10 21:23:07 -08:00
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
let llof = LLVMCreateObjectFile(llmb);
|
2015-03-25 17:06:52 -07:00
|
|
|
if llof as isize == 0 {
|
2014-01-01 13:03:26 -08:00
|
|
|
// LLVMCreateObjectFile took ownership of llmb
|
2016-10-22 18:37:35 +05:30
|
|
|
return None;
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
}
|
|
|
|
|
2016-10-22 18:37:35 +05:30
|
|
|
Some(ObjectFile { llof: llof })
|
2013-01-10 21:23:07 -08:00
|
|
|
}
|
|
|
|
}
|
2011-03-15 12:27:15 -07:00
|
|
|
}
|
|
|
|
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
impl Drop for ObjectFile {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
LLVMDisposeObjectFile(self.llof);
|
Add generation of static libraries to rustc
This commit implements the support necessary for generating both intermediate
and result static rust libraries. This is an implementation of my thoughts in
https://mail.mozilla.org/pipermail/rust-dev/2013-November/006686.html.
When compiling a library, we still retain the "lib" option, although now there
are "rlib", "staticlib", and "dylib" as options for crate_type (and these are
stackable). The idea of "lib" is to generate the "compiler default" instead of
having too choose (although all are interchangeable). For now I have left the
"complier default" to be a dynamic library for size reasons.
Of the rust libraries, lib{std,extra,rustuv} will bootstrap with an
rlib/dylib pair, but lib{rustc,syntax,rustdoc,rustpkg} will only be built as a
dynamic object. I chose this for size reasons, but also because you're probably
not going to be embedding the rustc compiler anywhere any time soon.
Other than the options outlined above, there are a few defaults/preferences that
are now opinionated in the compiler:
* If both a .dylib and .rlib are found for a rust library, the compiler will
prefer the .rlib variant. This is overridable via the -Z prefer-dynamic option
* If generating a "lib", the compiler will generate a dynamic library. This is
overridable by explicitly saying what flavor you'd like (rlib, staticlib,
dylib).
* If no options are passed to the command line, and no crate_type is found in
the destination crate, then an executable is generated
With this change, you can successfully build a rust program with 0 dynamic
dependencies on rust libraries. There is still a dynamic dependency on
librustrt, but I plan on removing that in a subsequent commit.
This change includes no tests just yet. Our current testing
infrastructure/harnesses aren't very amenable to doing flavorful things with
linking, so I'm planning on adding a new mode of testing which I believe belongs
as a separate commit.
Closes #552
2013-11-15 14:03:29 -08:00
|
|
|
}
|
2013-01-10 21:23:07 -08:00
|
|
|
}
|
2011-03-15 12:27:15 -07:00
|
|
|
}
|
|
|
|
|
2016-10-22 18:37:35 +05:30
|
|
|
// Memory-managed interface to section iterators.
|
2011-03-15 12:27:15 -07:00
|
|
|
|
2014-04-22 03:53:51 +03:00
|
|
|
pub struct SectionIter {
|
2016-10-22 18:37:35 +05:30
|
|
|
pub llsi: SectionIteratorRef,
|
2013-02-27 19:13:53 -05:00
|
|
|
}
|
|
|
|
|
2014-04-22 03:53:51 +03:00
|
|
|
impl Drop for SectionIter {
|
2013-09-16 21:18:07 -04:00
|
|
|
fn drop(&mut self) {
|
2013-01-10 21:23:07 -08:00
|
|
|
unsafe {
|
2014-07-07 17:58:01 -07:00
|
|
|
LLVMDisposeSectionIterator(self.llsi);
|
2013-01-10 21:23:07 -08:00
|
|
|
}
|
|
|
|
}
|
2011-03-15 12:27:15 -07:00
|
|
|
}
|
|
|
|
|
2013-02-19 02:40:42 -05:00
|
|
|
pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
|
2016-10-22 18:37:35 +05:30
|
|
|
unsafe { SectionIter { llsi: LLVMGetSections(llof) } }
|
2011-03-15 12:27:15 -07:00
|
|
|
}
|
2014-07-05 13:24:57 -07:00
|
|
|
|
2014-05-28 22:26:56 -07:00
|
|
|
/// Safe wrapper around `LLVMGetParam`, because segfaults are no fun.
|
|
|
|
pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
|
|
|
|
unsafe {
|
2016-12-20 10:46:44 -07:00
|
|
|
assert!(index < LLVMCountParams(llfn),
|
|
|
|
"out of bounds argument access: {} out of {} arguments", index, LLVMCountParams(llfn));
|
2014-05-28 22:26:56 -07:00
|
|
|
LLVMGetParam(llfn, index)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-19 03:09:55 +03:00
|
|
|
fn get_params(llfn: ValueRef) -> Vec<ValueRef> {
|
2015-06-18 20:07:36 +02:00
|
|
|
unsafe {
|
|
|
|
let num_params = LLVMCountParams(llfn);
|
|
|
|
let mut params = Vec::with_capacity(num_params as usize);
|
|
|
|
for idx in 0..num_params {
|
|
|
|
params.push(LLVMGetParam(llfn, idx));
|
|
|
|
}
|
|
|
|
|
|
|
|
params
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-22 18:37:35 +05:30
|
|
|
pub fn build_string<F>(f: F) -> Option<String>
|
|
|
|
where F: FnOnce(RustStringRef)
|
|
|
|
{
|
2014-09-09 23:12:09 -07:00
|
|
|
let mut buf = RefCell::new(Vec::new());
|
|
|
|
f(&mut buf as RustStringRepr as RustStringRef);
|
2014-11-20 09:23:43 -08:00
|
|
|
String::from_utf8(buf.into_inner()).ok()
|
2014-09-09 23:12:09 -07:00
|
|
|
}
|
|
|
|
|
2014-09-12 08:17:58 -07:00
|
|
|
pub unsafe fn twine_to_string(tr: TwineRef) -> String {
|
2016-10-22 18:37:35 +05:30
|
|
|
build_string(|s| LLVMRustWriteTwineToString(tr, s)).expect("got a non-UTF8 Twine from LLVM")
|
2014-09-12 08:17:58 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
|
2016-08-02 02:35:09 +03:00
|
|
|
build_string(|s| LLVMRustWriteDebugLocToString(c, tr, s))
|
2014-09-12 08:17:58 -07:00
|
|
|
.expect("got a non-UTF8 DebugLoc from LLVM")
|
|
|
|
}
|
|
|
|
|
2015-08-21 23:43:56 -05:00
|
|
|
pub fn initialize_available_targets() {
|
|
|
|
macro_rules! init_target(
|
2016-01-21 15:39:22 -08:00
|
|
|
($cfg:meta, $($method:ident),*) => { {
|
2015-08-21 23:43:56 -05:00
|
|
|
#[cfg($cfg)]
|
|
|
|
fn init() {
|
2016-01-21 15:39:22 -08:00
|
|
|
extern {
|
|
|
|
$(fn $method();)*
|
|
|
|
}
|
2015-08-21 23:43:56 -05:00
|
|
|
unsafe {
|
2016-01-21 15:39:22 -08:00
|
|
|
$($method();)*
|
2015-08-21 23:43:56 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#[cfg(not($cfg))]
|
|
|
|
fn init() { }
|
|
|
|
init();
|
|
|
|
} }
|
|
|
|
);
|
2016-01-21 15:39:22 -08:00
|
|
|
init_target!(llvm_component = "x86",
|
|
|
|
LLVMInitializeX86TargetInfo,
|
|
|
|
LLVMInitializeX86Target,
|
|
|
|
LLVMInitializeX86TargetMC,
|
|
|
|
LLVMInitializeX86AsmPrinter,
|
|
|
|
LLVMInitializeX86AsmParser);
|
|
|
|
init_target!(llvm_component = "arm",
|
|
|
|
LLVMInitializeARMTargetInfo,
|
|
|
|
LLVMInitializeARMTarget,
|
|
|
|
LLVMInitializeARMTargetMC,
|
|
|
|
LLVMInitializeARMAsmPrinter,
|
|
|
|
LLVMInitializeARMAsmParser);
|
|
|
|
init_target!(llvm_component = "aarch64",
|
|
|
|
LLVMInitializeAArch64TargetInfo,
|
|
|
|
LLVMInitializeAArch64Target,
|
|
|
|
LLVMInitializeAArch64TargetMC,
|
|
|
|
LLVMInitializeAArch64AsmPrinter,
|
|
|
|
LLVMInitializeAArch64AsmParser);
|
|
|
|
init_target!(llvm_component = "mips",
|
|
|
|
LLVMInitializeMipsTargetInfo,
|
|
|
|
LLVMInitializeMipsTarget,
|
|
|
|
LLVMInitializeMipsTargetMC,
|
|
|
|
LLVMInitializeMipsAsmPrinter,
|
|
|
|
LLVMInitializeMipsAsmParser);
|
|
|
|
init_target!(llvm_component = "powerpc",
|
|
|
|
LLVMInitializePowerPCTargetInfo,
|
|
|
|
LLVMInitializePowerPCTarget,
|
|
|
|
LLVMInitializePowerPCTargetMC,
|
|
|
|
LLVMInitializePowerPCAsmPrinter,
|
|
|
|
LLVMInitializePowerPCAsmParser);
|
|
|
|
init_target!(llvm_component = "pnacl",
|
|
|
|
LLVMInitializePNaClTargetInfo,
|
|
|
|
LLVMInitializePNaClTarget,
|
|
|
|
LLVMInitializePNaClTargetMC);
|
2016-08-26 21:05:16 -05:00
|
|
|
init_target!(llvm_component = "systemz",
|
|
|
|
LLVMInitializeSystemZTargetInfo,
|
|
|
|
LLVMInitializeSystemZTarget,
|
|
|
|
LLVMInitializeSystemZTargetMC,
|
|
|
|
LLVMInitializeSystemZAsmPrinter,
|
|
|
|
LLVMInitializeSystemZAsmParser);
|
2016-08-06 12:52:17 +02:00
|
|
|
init_target!(llvm_component = "jsbackend",
|
|
|
|
LLVMInitializeJSBackendTargetInfo,
|
|
|
|
LLVMInitializeJSBackendTarget,
|
|
|
|
LLVMInitializeJSBackendTargetMC);
|
2016-11-09 14:00:26 -05:00
|
|
|
init_target!(llvm_component = "msp430",
|
|
|
|
LLVMInitializeMSP430TargetInfo,
|
|
|
|
LLVMInitializeMSP430Target,
|
|
|
|
LLVMInitializeMSP430TargetMC,
|
|
|
|
LLVMInitializeMSP430AsmPrinter);
|
2016-12-11 23:12:46 -05:00
|
|
|
init_target!(llvm_component = "sparc",
|
|
|
|
LLVMInitializeSparcTargetInfo,
|
|
|
|
LLVMInitializeSparcTarget,
|
|
|
|
LLVMInitializeSparcTargetMC,
|
|
|
|
LLVMInitializeSparcAsmPrinter,
|
|
|
|
LLVMInitializeSparcAsmParser);
|
2016-12-22 16:24:29 -05:00
|
|
|
init_target!(llvm_component = "nvptx",
|
|
|
|
LLVMInitializeNVPTXTargetInfo,
|
|
|
|
LLVMInitializeNVPTXTarget,
|
|
|
|
LLVMInitializeNVPTXTargetMC,
|
|
|
|
LLVMInitializeNVPTXAsmPrinter);
|
2017-04-09 02:03:31 -04:00
|
|
|
init_target!(llvm_component = "hexagon",
|
|
|
|
LLVMInitializeHexagonTargetInfo,
|
|
|
|
LLVMInitializeHexagonTarget,
|
|
|
|
LLVMInitializeHexagonTargetMC,
|
|
|
|
LLVMInitializeHexagonAsmPrinter,
|
|
|
|
LLVMInitializeHexagonAsmParser);
|
2017-06-16 15:43:43 -07:00
|
|
|
init_target!(llvm_component = "webassembly",
|
|
|
|
LLVMInitializeWebAssemblyTargetInfo,
|
|
|
|
LLVMInitializeWebAssemblyTarget,
|
|
|
|
LLVMInitializeWebAssemblyTargetMC,
|
|
|
|
LLVMInitializeWebAssemblyAsmPrinter);
|
2015-08-21 23:43:56 -05:00
|
|
|
}
|
|
|
|
|
2015-10-22 22:07:19 -07:00
|
|
|
pub fn last_error() -> Option<String> {
|
|
|
|
unsafe {
|
|
|
|
let cstr = LLVMRustGetLastError();
|
|
|
|
if cstr.is_null() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
let err = CStr::from_ptr(cstr).to_bytes();
|
|
|
|
let err = String::from_utf8_lossy(err).to_string();
|
|
|
|
libc::free(cstr as *mut _);
|
|
|
|
Some(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-23 18:18:44 -07:00
|
|
|
pub struct OperandBundleDef {
|
|
|
|
inner: OperandBundleDefRef,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl OperandBundleDef {
|
|
|
|
pub fn new(name: &str, vals: &[ValueRef]) -> OperandBundleDef {
|
|
|
|
let name = CString::new(name).unwrap();
|
|
|
|
let def = unsafe {
|
2016-10-22 18:37:35 +05:30
|
|
|
LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
|
2015-10-23 18:18:44 -07:00
|
|
|
};
|
|
|
|
OperandBundleDef { inner: def }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn raw(&self) -> OperandBundleDefRef {
|
|
|
|
self.inner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for OperandBundleDef {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
LLVMRustFreeOperandBundleDef(self.inner);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|