audit LLVM C++ types in ArchiveWrapper and PassWrapper
This commit is contained in:
parent
81df89fc2d
commit
696691e3c4
@ -40,13 +40,9 @@ pub use self::TypeKind::*;
|
||||
pub use self::AtomicBinOp::*;
|
||||
pub use self::AtomicOrdering::*;
|
||||
pub use self::SynchronizationScope::*;
|
||||
pub use self::FileType::*;
|
||||
pub use self::MetadataType::*;
|
||||
pub use self::AsmDialect::*;
|
||||
pub use self::CodeGenOptLevel::*;
|
||||
pub use self::CodeGenOptSize::*;
|
||||
pub use self::RelocMode::*;
|
||||
pub use self::CodeGenModel::*;
|
||||
pub use self::DiagnosticKind::*;
|
||||
pub use self::CallConv::*;
|
||||
pub use self::Visibility::*;
|
||||
@ -75,9 +71,26 @@ pub type Bool = c_uint;
|
||||
pub const True: Bool = 1 as Bool;
|
||||
pub const False: Bool = 0 as Bool;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum LLVMRustResult {
|
||||
Success = 0,
|
||||
Failure = 1
|
||||
}
|
||||
|
||||
impl LLVMRustResult {
|
||||
pub fn into_result(self) -> Result<(), ()> {
|
||||
match self {
|
||||
LLVMRustResult::Success => Ok(()),
|
||||
LLVMRustResult::Failure => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Consts for the LLVM CallConv type, pre-cast to usize.
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(C)]
|
||||
pub enum CallConv {
|
||||
CCallConv = 0,
|
||||
FastCallConv = 8,
|
||||
@ -89,6 +102,7 @@ pub enum CallConv {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub enum Visibility {
|
||||
LLVMDefaultVisibility = 0,
|
||||
HiddenVisibility = 1,
|
||||
@ -100,6 +114,7 @@ pub enum Visibility {
|
||||
// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
|
||||
// they've been removed in upstream LLVM commit r203866.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[repr(C)]
|
||||
pub enum Linkage {
|
||||
ExternalLinkage = 0,
|
||||
AvailableExternallyLinkage = 1,
|
||||
@ -337,12 +352,12 @@ pub enum SynchronizationScope {
|
||||
CrossThread = 1
|
||||
}
|
||||
|
||||
// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum FileType {
|
||||
AssemblyFileType = 0,
|
||||
ObjectFileType = 1
|
||||
Other,
|
||||
AssemblyFile,
|
||||
ObjectFile,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -371,10 +386,11 @@ pub enum AsmDialect {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(C)]
|
||||
pub enum CodeGenOptLevel {
|
||||
CodeGenLevelNone = 0,
|
||||
CodeGenLevelLess = 1,
|
||||
CodeGenLevelDefault = 2,
|
||||
CodeGenLevelAggressive = 3,
|
||||
Other,
|
||||
None,
|
||||
Less,
|
||||
Default,
|
||||
Aggressive,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
@ -388,21 +404,22 @@ pub enum CodeGenOptSize {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(C)]
|
||||
pub enum RelocMode {
|
||||
RelocDefault = 0,
|
||||
RelocStatic = 1,
|
||||
RelocPIC = 2,
|
||||
RelocDynamicNoPic = 3,
|
||||
Default = 0,
|
||||
Static = 1,
|
||||
PIC = 2,
|
||||
DynamicNoPic = 3,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum CodeGenModel {
|
||||
CodeModelDefault = 0,
|
||||
CodeModelJITDefault = 1,
|
||||
CodeModelSmall = 2,
|
||||
CodeModelKernel = 3,
|
||||
CodeModelMedium = 4,
|
||||
CodeModelLarge = 5,
|
||||
pub enum CodeModel {
|
||||
Other,
|
||||
Default,
|
||||
JITDefault,
|
||||
Small,
|
||||
Kernel,
|
||||
Medium,
|
||||
Large,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -421,6 +438,7 @@ pub enum DiagnosticKind {
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ArchiveKind {
|
||||
Other,
|
||||
K_GNU,
|
||||
K_MIPS64,
|
||||
K_BSD,
|
||||
@ -444,10 +462,10 @@ impl FromStr for ArchiveKind {
|
||||
/// Represents the different LLVM passes Rust supports
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
#[repr(C)]
|
||||
pub enum SupportedPassKind {
|
||||
pub enum PassKind {
|
||||
Other,
|
||||
Function,
|
||||
Module,
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
// Opaque pointer types
|
||||
@ -2021,7 +2039,7 @@ extern {
|
||||
pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
|
||||
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
|
||||
|
||||
pub fn LLVMRustPassKind(Pass: PassRef) -> SupportedPassKind;
|
||||
pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind;
|
||||
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
|
||||
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
|
||||
|
||||
@ -2031,7 +2049,7 @@ extern {
|
||||
pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
|
||||
CPU: *const c_char,
|
||||
Features: *const c_char,
|
||||
Model: CodeGenModel,
|
||||
Model: CodeModel,
|
||||
Reloc: RelocMode,
|
||||
Level: CodeGenOptLevel,
|
||||
UseSoftFP: bool,
|
||||
@ -2057,7 +2075,8 @@ extern {
|
||||
PM: PassManagerRef,
|
||||
M: ModuleRef,
|
||||
Output: *const c_char,
|
||||
FileType: FileType) -> bool;
|
||||
FileType: FileType)
|
||||
-> LLVMRustResult;
|
||||
pub fn LLVMRustPrintModule(PM: PassManagerRef,
|
||||
M: ModuleRef,
|
||||
Output: *const c_char);
|
||||
@ -2123,7 +2142,8 @@ extern {
|
||||
NumMembers: size_t,
|
||||
Members: *const RustArchiveMemberRef,
|
||||
WriteSymbtab: bool,
|
||||
Kind: ArchiveKind) -> c_int;
|
||||
Kind: ArchiveKind) ->
|
||||
LLVMRustResult;
|
||||
pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
|
||||
Name: *const c_char,
|
||||
Child: ArchiveChildRef) -> RustArchiveMemberRef;
|
||||
|
@ -293,7 +293,7 @@ impl<'a> ArchiveBuilder<'a> {
|
||||
members.as_ptr(),
|
||||
self.should_update_symbols,
|
||||
kind);
|
||||
let ret = if r != 0 {
|
||||
let ret = if r.into_result().is_err() {
|
||||
let err = llvm::LLVMRustGetLastError();
|
||||
let msg = if err.is_null() {
|
||||
"failed to write archive".to_string()
|
||||
|
@ -54,7 +54,7 @@ pub fn write_output_file(
|
||||
let output_c = path2cstr(output);
|
||||
let result = llvm::LLVMRustWriteOutputFile(
|
||||
target, pm, m, output_c.as_ptr(), file_type);
|
||||
if !result {
|
||||
if result.into_result().is_err() {
|
||||
llvm_err(handler, format!("could not write output to {}", output.display()));
|
||||
}
|
||||
}
|
||||
@ -138,11 +138,11 @@ fn target_feature(sess: &Session) -> String {
|
||||
|
||||
fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
|
||||
match optimize {
|
||||
config::OptLevel::No => llvm::CodeGenLevelNone,
|
||||
config::OptLevel::Less => llvm::CodeGenLevelLess,
|
||||
config::OptLevel::Default => llvm::CodeGenLevelDefault,
|
||||
config::OptLevel::Aggressive => llvm::CodeGenLevelAggressive,
|
||||
_ => llvm::CodeGenLevelDefault,
|
||||
config::OptLevel::No => llvm::CodeGenOptLevel::None,
|
||||
config::OptLevel::Less => llvm::CodeGenOptLevel::Less,
|
||||
config::OptLevel::Default => llvm::CodeGenOptLevel::Default,
|
||||
config::OptLevel::Aggressive => llvm::CodeGenOptLevel::Aggressive,
|
||||
_ => llvm::CodeGenOptLevel::Default,
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,11 +169,11 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
|
||||
};
|
||||
|
||||
let code_model = match code_model_arg {
|
||||
"default" => llvm::CodeModelDefault,
|
||||
"small" => llvm::CodeModelSmall,
|
||||
"kernel" => llvm::CodeModelKernel,
|
||||
"medium" => llvm::CodeModelMedium,
|
||||
"large" => llvm::CodeModelLarge,
|
||||
"default" => llvm::CodeModel::Default,
|
||||
"small" => llvm::CodeModel::Small,
|
||||
"kernel" => llvm::CodeModel::Kernel,
|
||||
"medium" => llvm::CodeModel::Medium,
|
||||
"large" => llvm::CodeModel::Large,
|
||||
_ => {
|
||||
sess.err(&format!("{:?} is not a valid code model",
|
||||
sess.opts
|
||||
@ -449,9 +449,9 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
||||
return false;
|
||||
}
|
||||
let pass_manager = match llvm::LLVMRustPassKind(pass) {
|
||||
llvm::SupportedPassKind::Function => fpm,
|
||||
llvm::SupportedPassKind::Module => mpm,
|
||||
llvm::SupportedPassKind::Unsupported => {
|
||||
llvm::PassKind::Function => fpm,
|
||||
llvm::PassKind::Module => mpm,
|
||||
llvm::PassKind::Other => {
|
||||
cgcx.handler.err("Encountered LLVM pass kind we can't handle");
|
||||
return true
|
||||
},
|
||||
@ -579,7 +579,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
||||
};
|
||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||
write_output_file(cgcx.handler, tm, cpm, llmod, &path,
|
||||
llvm::AssemblyFileType);
|
||||
llvm::FileType::AssemblyFile);
|
||||
});
|
||||
if config.emit_obj {
|
||||
llvm::LLVMDisposeModule(llmod);
|
||||
@ -588,7 +588,8 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
|
||||
|
||||
if write_obj {
|
||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
||||
write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out, llvm::ObjectFileType);
|
||||
write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out,
|
||||
llvm::FileType::ObjectFile);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1078,7 +1079,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
|
||||
// reasonable defaults and prepare it to actually populate the pass
|
||||
// manager.
|
||||
let builder = llvm::LLVMPassManagerBuilderCreate();
|
||||
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenLevelNone);
|
||||
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
|
||||
let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
|
||||
let inline_threshold = config.inline_threshold;
|
||||
|
||||
@ -1102,7 +1103,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
|
||||
(_, _, Some(t)) => {
|
||||
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32);
|
||||
}
|
||||
(llvm::CodeGenLevelAggressive, _, _) => {
|
||||
(llvm::CodeGenOptLevel::Aggressive, _, _) => {
|
||||
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
|
||||
}
|
||||
(_, llvm::CodeGenOptSizeDefault, _) => {
|
||||
@ -1111,15 +1112,18 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
|
||||
(_, llvm::CodeGenOptSizeAggressive, _) => {
|
||||
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 25);
|
||||
}
|
||||
(llvm::CodeGenLevelNone, _, _) => {
|
||||
(llvm::CodeGenOptLevel::None, _, _) => {
|
||||
llvm::LLVMRustAddAlwaysInlinePass(builder, false);
|
||||
}
|
||||
(llvm::CodeGenLevelLess, _, _) => {
|
||||
(llvm::CodeGenOptLevel::Less, _, _) => {
|
||||
llvm::LLVMRustAddAlwaysInlinePass(builder, true);
|
||||
}
|
||||
(llvm::CodeGenLevelDefault, _, _) => {
|
||||
(llvm::CodeGenOptLevel::Default, _, _) => {
|
||||
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
|
||||
}
|
||||
(llvm::CodeGenOptLevel::Other, _, _) => {
|
||||
bug!("CodeGenOptLevel::Other selected")
|
||||
}
|
||||
}
|
||||
|
||||
f(builder);
|
||||
|
@ -325,10 +325,10 @@ pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
|
||||
};
|
||||
|
||||
match reloc_model_arg {
|
||||
"pic" => llvm::RelocPIC,
|
||||
"static" => llvm::RelocStatic,
|
||||
"default" => llvm::RelocDefault,
|
||||
"dynamic-no-pic" => llvm::RelocDynamicNoPic,
|
||||
"pic" => llvm::RelocMode::PIC,
|
||||
"static" => llvm::RelocMode::Static,
|
||||
"default" => llvm::RelocMode::Default,
|
||||
"dynamic-no-pic" => llvm::RelocMode::DynamicNoPic,
|
||||
_ => {
|
||||
sess.err(&format!("{:?} is not a valid relocation mode",
|
||||
sess.opts
|
||||
@ -347,7 +347,7 @@ fn is_any_library(sess: &Session) -> bool {
|
||||
}
|
||||
|
||||
pub fn is_pie_binary(sess: &Session) -> bool {
|
||||
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocPIC
|
||||
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
|
||||
}
|
||||
|
||||
unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
|
||||
|
@ -16,24 +16,62 @@
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
||||
struct LLVMRustArchiveMember {
|
||||
struct RustArchiveMember {
|
||||
const char *filename;
|
||||
const char *name;
|
||||
Archive::Child child;
|
||||
|
||||
LLVMRustArchiveMember(): filename(NULL), name(NULL),
|
||||
RustArchiveMember(): filename(NULL), name(NULL),
|
||||
#if LLVM_VERSION_MINOR >= 8
|
||||
child(NULL, NULL, NULL)
|
||||
#else
|
||||
child(NULL, NULL)
|
||||
#endif
|
||||
{}
|
||||
~LLVMRustArchiveMember() {}
|
||||
~RustArchiveMember() {}
|
||||
};
|
||||
|
||||
typedef OwningBinary<Archive> RustArchive;
|
||||
|
||||
extern "C" void*
|
||||
struct RustArchiveIterator {
|
||||
Archive::child_iterator cur;
|
||||
Archive::child_iterator end;
|
||||
#if LLVM_VERSION_MINOR >= 9
|
||||
Error err;
|
||||
#endif
|
||||
};
|
||||
|
||||
enum class LLVMRustArchiveKind {
|
||||
Other,
|
||||
GNU,
|
||||
MIPS64,
|
||||
BSD,
|
||||
COFF,
|
||||
};
|
||||
|
||||
static Archive::Kind
|
||||
from_rust(LLVMRustArchiveKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case LLVMRustArchiveKind::GNU:
|
||||
return Archive::K_GNU;
|
||||
case LLVMRustArchiveKind::MIPS64:
|
||||
return Archive::K_MIPS64;
|
||||
case LLVMRustArchiveKind::BSD:
|
||||
return Archive::K_BSD;
|
||||
case LLVMRustArchiveKind::COFF:
|
||||
return Archive::K_COFF;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
typedef OwningBinary<Archive> *LLVMRustArchiveRef;
|
||||
typedef RustArchiveMember *LLVMRustArchiveMemberRef;
|
||||
typedef Archive::Child *LLVMRustArchiveChildRef;
|
||||
typedef Archive::Child const *LLVMRustArchiveChildConstRef;
|
||||
typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
|
||||
|
||||
extern "C" LLVMRustArchiveRef
|
||||
LLVMRustOpenArchive(char *path) {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
|
||||
-1,
|
||||
@ -66,20 +104,12 @@ LLVMRustOpenArchive(char *path) {
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
LLVMRustDestroyArchive(RustArchive *ar) {
|
||||
LLVMRustDestroyArchive(LLVMRustArchiveRef ar) {
|
||||
delete ar;
|
||||
}
|
||||
|
||||
struct RustArchiveIterator {
|
||||
Archive::child_iterator cur;
|
||||
Archive::child_iterator end;
|
||||
#if LLVM_VERSION_MINOR >= 9
|
||||
Error err;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern "C" RustArchiveIterator*
|
||||
LLVMRustArchiveIteratorNew(RustArchive *ra) {
|
||||
extern "C" LLVMRustArchiveIteratorRef
|
||||
LLVMRustArchiveIteratorNew(LLVMRustArchiveRef ra) {
|
||||
Archive *ar = ra->getBinary();
|
||||
RustArchiveIterator *rai = new RustArchiveIterator();
|
||||
#if LLVM_VERSION_MINOR <= 8
|
||||
@ -95,8 +125,8 @@ LLVMRustArchiveIteratorNew(RustArchive *ra) {
|
||||
return rai;
|
||||
}
|
||||
|
||||
extern "C" const Archive::Child*
|
||||
LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
|
||||
extern "C" LLVMRustArchiveChildConstRef
|
||||
LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef rai) {
|
||||
#if LLVM_VERSION_MINOR >= 9
|
||||
if (rai->err) {
|
||||
LLVMRustSetLastError(toString(std::move(rai->err)).c_str());
|
||||
@ -122,17 +152,17 @@ LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
LLVMRustArchiveChildFree(Archive::Child *child) {
|
||||
LLVMRustArchiveChildFree(LLVMRustArchiveChildRef child) {
|
||||
delete child;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
|
||||
LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef rai) {
|
||||
delete rai;
|
||||
}
|
||||
|
||||
extern "C" const char*
|
||||
LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
|
||||
LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef child, size_t *size) {
|
||||
ErrorOr<StringRef> name_or_err = child->getName();
|
||||
if (name_or_err.getError())
|
||||
return NULL;
|
||||
@ -142,7 +172,7 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
|
||||
}
|
||||
|
||||
extern "C" const char*
|
||||
LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
|
||||
LLVMRustArchiveChildData(LLVMRustArchiveChildRef child, size_t *size) {
|
||||
StringRef buf;
|
||||
ErrorOr<StringRef> buf_or_err = child->getBuffer();
|
||||
if (buf_or_err.getError()) {
|
||||
@ -154,9 +184,10 @@ LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
|
||||
return buf.data();
|
||||
}
|
||||
|
||||
extern "C" LLVMRustArchiveMember*
|
||||
LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
|
||||
LLVMRustArchiveMember *Member = new LLVMRustArchiveMember;
|
||||
extern "C" LLVMRustArchiveMemberRef
|
||||
LLVMRustArchiveMemberNew(char *Filename, char *Name,
|
||||
LLVMRustArchiveChildRef child) {
|
||||
RustArchiveMember *Member = new RustArchiveMember;
|
||||
Member->filename = Filename;
|
||||
Member->name = Name;
|
||||
if (child)
|
||||
@ -165,22 +196,23 @@ LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
LLVMRustArchiveMemberFree(LLVMRustArchiveMember *Member) {
|
||||
LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
|
||||
delete Member;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
extern "C" LLVMRustResult
|
||||
LLVMRustWriteArchive(char *Dst,
|
||||
size_t NumMembers,
|
||||
const LLVMRustArchiveMember **NewMembers,
|
||||
const LLVMRustArchiveMemberRef *NewMembers,
|
||||
bool WriteSymbtab,
|
||||
Archive::Kind Kind) {
|
||||
LLVMRustArchiveKind rust_kind) {
|
||||
|
||||
#if LLVM_VERSION_MINOR <= 8
|
||||
std::vector<NewArchiveIterator> Members;
|
||||
#else
|
||||
std::vector<NewArchiveMember> Members;
|
||||
#endif
|
||||
auto Kind = from_rust(rust_kind);
|
||||
|
||||
for (size_t i = 0; i < NumMembers; i++) {
|
||||
auto Member = NewMembers[i];
|
||||
@ -190,7 +222,7 @@ LLVMRustWriteArchive(char *Dst,
|
||||
Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true);
|
||||
if (!MOrErr) {
|
||||
LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
|
||||
return -1;
|
||||
return LLVMRustResult::Failure;
|
||||
}
|
||||
Members.push_back(std::move(*MOrErr));
|
||||
#elif LLVM_VERSION_MINOR == 8
|
||||
@ -205,7 +237,7 @@ LLVMRustWriteArchive(char *Dst,
|
||||
Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true);
|
||||
if (!MOrErr) {
|
||||
LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
|
||||
return -1;
|
||||
return LLVMRustResult::Failure;
|
||||
}
|
||||
Members.push_back(std::move(*MOrErr));
|
||||
#endif
|
||||
@ -217,7 +249,7 @@ LLVMRustWriteArchive(char *Dst,
|
||||
auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true);
|
||||
#endif
|
||||
if (!pair.second)
|
||||
return 0;
|
||||
return LLVMRustResult::Success;
|
||||
LLVMRustSetLastError(pair.second.message().c_str());
|
||||
return -1;
|
||||
return LLVMRustResult::Failure;
|
||||
}
|
||||
|
@ -54,41 +54,48 @@ LLVMInitializePasses() {
|
||||
initializeTarget(Registry);
|
||||
}
|
||||
|
||||
|
||||
enum class SupportedPassKind {
|
||||
enum class LLVMRustPassKind {
|
||||
Other,
|
||||
Function,
|
||||
Module,
|
||||
Unsupported
|
||||
};
|
||||
|
||||
extern "C" Pass*
|
||||
static LLVMRustPassKind
|
||||
to_rust(PassKind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case PT_Function:
|
||||
return LLVMRustPassKind::Function;
|
||||
case PT_Module:
|
||||
return LLVMRustPassKind::Module;
|
||||
default:
|
||||
return LLVMRustPassKind::Other;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" LLVMPassRef
|
||||
LLVMRustFindAndCreatePass(const char *PassName) {
|
||||
StringRef SR(PassName);
|
||||
PassRegistry *PR = PassRegistry::getPassRegistry();
|
||||
|
||||
const PassInfo *PI = PR->getPassInfo(SR);
|
||||
if (PI) {
|
||||
return PI->createPass();
|
||||
return wrap(PI->createPass());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" SupportedPassKind
|
||||
LLVMRustPassKind(Pass *pass) {
|
||||
assert(pass);
|
||||
PassKind passKind = pass->getPassKind();
|
||||
if (passKind == PT_Module) {
|
||||
return SupportedPassKind::Module;
|
||||
} else if (passKind == PT_Function) {
|
||||
return SupportedPassKind::Function;
|
||||
} else {
|
||||
return SupportedPassKind::Unsupported;
|
||||
}
|
||||
extern "C" LLVMRustPassKind
|
||||
LLVMRustPassKind(LLVMPassRef rust_pass) {
|
||||
assert(rust_pass);
|
||||
Pass *pass = unwrap(rust_pass);
|
||||
return to_rust(pass->getPassKind());
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
|
||||
assert(pass);
|
||||
LLVMRustAddPass(LLVMPassManagerRef PM, LLVMPassRef rust_pass) {
|
||||
assert(rust_pass);
|
||||
Pass *pass = unwrap(rust_pass);
|
||||
PassManagerBase *pm = unwrap(PM);
|
||||
pm->add(pass);
|
||||
}
|
||||
@ -162,13 +169,69 @@ LLVMRustHasFeature(LLVMTargetMachineRef TM,
|
||||
return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
|
||||
}
|
||||
|
||||
enum class LLVMRustCodeModel {
|
||||
Other,
|
||||
Default,
|
||||
JITDefault,
|
||||
Small,
|
||||
Kernel,
|
||||
Medium,
|
||||
Large,
|
||||
};
|
||||
|
||||
static CodeModel::Model
|
||||
from_rust(LLVMRustCodeModel model)
|
||||
{
|
||||
switch (model) {
|
||||
case LLVMRustCodeModel::Default:
|
||||
return CodeModel::Default;
|
||||
case LLVMRustCodeModel::JITDefault:
|
||||
return CodeModel::JITDefault;
|
||||
case LLVMRustCodeModel::Small:
|
||||
return CodeModel::Small;
|
||||
case LLVMRustCodeModel::Kernel:
|
||||
return CodeModel::Kernel;
|
||||
case LLVMRustCodeModel::Medium:
|
||||
return CodeModel::Medium;
|
||||
case LLVMRustCodeModel::Large:
|
||||
return CodeModel::Large;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
enum class LLVMRustCodeGenOptLevel {
|
||||
Other,
|
||||
None,
|
||||
Less,
|
||||
Default,
|
||||
Aggressive,
|
||||
};
|
||||
|
||||
static CodeGenOpt::Level
|
||||
from_rust(LLVMRustCodeGenOptLevel level)
|
||||
{
|
||||
switch (level) {
|
||||
case LLVMRustCodeGenOptLevel::None:
|
||||
return CodeGenOpt::None;
|
||||
case LLVMRustCodeGenOptLevel::Less:
|
||||
return CodeGenOpt::Less;
|
||||
case LLVMRustCodeGenOptLevel::Default:
|
||||
return CodeGenOpt::Default;
|
||||
case LLVMRustCodeGenOptLevel::Aggressive:
|
||||
return CodeGenOpt::Aggressive;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" LLVMTargetMachineRef
|
||||
LLVMRustCreateTargetMachine(const char *triple,
|
||||
const char *cpu,
|
||||
const char *feature,
|
||||
CodeModel::Model CM,
|
||||
LLVMRustCodeModel rust_CM,
|
||||
LLVMRelocMode Reloc,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
LLVMRustCodeGenOptLevel rust_OptLevel,
|
||||
bool UseSoftFloat,
|
||||
bool PositionIndependentExecutable,
|
||||
bool FunctionSections,
|
||||
@ -179,6 +242,9 @@ LLVMRustCreateTargetMachine(const char *triple,
|
||||
#else
|
||||
Optional<Reloc::Model> RM;
|
||||
#endif
|
||||
auto CM = from_rust(rust_CM);
|
||||
auto OptLevel = from_rust(rust_OptLevel);
|
||||
|
||||
switch (Reloc){
|
||||
case LLVMRelocStatic:
|
||||
RM = Reloc::Static;
|
||||
@ -251,14 +317,14 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
|
||||
|
||||
extern "C" void
|
||||
LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
LLVMRustCodeGenOptLevel OptLevel,
|
||||
bool MergeFunctions,
|
||||
bool SLPVectorize,
|
||||
bool LoopVectorize) {
|
||||
// Ignore mergefunc for now as enabling it causes crashes.
|
||||
//unwrap(PMB)->MergeFunctions = MergeFunctions;
|
||||
unwrap(PMB)->SLPVectorize = SLPVectorize;
|
||||
unwrap(PMB)->OptLevel = OptLevel;
|
||||
unwrap(PMB)->OptLevel = from_rust(OptLevel);
|
||||
unwrap(PMB)->LoopVectorize = LoopVectorize;
|
||||
}
|
||||
|
||||
@ -314,13 +380,33 @@ LLVMRustSetLLVMOptions(int Argc, char **Argv) {
|
||||
cl::ParseCommandLineOptions(Argc, Argv);
|
||||
}
|
||||
|
||||
extern "C" bool
|
||||
enum class LLVMRustFileType {
|
||||
Other,
|
||||
AssemblyFile,
|
||||
ObjectFile,
|
||||
};
|
||||
|
||||
static TargetMachine::CodeGenFileType
|
||||
from_rust(LLVMRustFileType type)
|
||||
{
|
||||
switch (type) {
|
||||
case LLVMRustFileType::AssemblyFile:
|
||||
return TargetMachine::CGFT_AssemblyFile;
|
||||
case LLVMRustFileType::ObjectFile:
|
||||
return TargetMachine::CGFT_ObjectFile;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" LLVMRustResult
|
||||
LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
|
||||
LLVMPassManagerRef PMR,
|
||||
LLVMModuleRef M,
|
||||
const char *path,
|
||||
TargetMachine::CodeGenFileType FileType) {
|
||||
LLVMRustFileType rust_FileType) {
|
||||
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
|
||||
auto FileType = from_rust(rust_FileType);
|
||||
|
||||
std::string ErrorInfo;
|
||||
std::error_code EC;
|
||||
@ -329,7 +415,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
|
||||
ErrorInfo = EC.message();
|
||||
if (ErrorInfo != "") {
|
||||
LLVMRustSetLastError(ErrorInfo.c_str());
|
||||
return false;
|
||||
return LLVMRustResult::Failure;
|
||||
}
|
||||
|
||||
unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
|
||||
@ -339,7 +425,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
|
||||
// stream (OS), so the only real safe place to delete this is here? Don't we
|
||||
// wish this was written in Rust?
|
||||
delete PM;
|
||||
return true;
|
||||
return LLVMRustResult::Success;
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
|
@ -1,2 +1,16 @@
|
||||
This directory currently contains some LLVM support code. This will generally
|
||||
be sent upstream to LLVM in time; for now it lives here.
|
||||
|
||||
NOTE: the LLVM C++ ABI is subject to between-version breakage and must *never*
|
||||
be exposed to Rust. To allow for easy auditing of that, all Rust-exposed types
|
||||
must be typedef-ed as "LLVMXyz", or "LLVMRustXyz" if they were defined here.
|
||||
|
||||
Functions that return a failure status and leave the error in
|
||||
the LLVM last error should return an LLVMRustResult rather than an
|
||||
int or anything to avoid confusion.
|
||||
|
||||
When translating enums, add a single `Other` variant as the first
|
||||
one to allow for new variants to be added. It should abort when used
|
||||
as an input.
|
||||
|
||||
All other types must not be typedef-ed as such.
|
||||
|
@ -58,6 +58,11 @@
|
||||
|
||||
void LLVMRustSetLastError(const char*);
|
||||
|
||||
enum class LLVMRustResult {
|
||||
Success,
|
||||
Failure
|
||||
};
|
||||
|
||||
typedef struct OpaqueRustString *RustStringRef;
|
||||
typedef struct LLVMOpaqueTwine *LLVMTwineRef;
|
||||
typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;
|
||||
|
Loading…
Reference in New Issue
Block a user