Auto merge of #35174 - arielb1:llvm-type-audit, r=eddyb

Audit C++ types in rustllvm

cc @eddyb

Fixes #35131
This commit is contained in:
bors 2016-08-03 07:52:08 -07:00 committed by GitHub
commit a0b4e67648
39 changed files with 2943 additions and 2662 deletions

View File

@ -24,7 +24,7 @@ LLVM_EXTRA_INCDIRS_$(1)= $$(call CFG_CC_INCLUDE_$(1),$(S)src/llvm/include) \
endif
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp \
RustWrapper.cpp PassWrapper.cpp \
ArchiveWrapper.cpp)
RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \

View File

@ -186,7 +186,7 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
let sopts = config::build_session_options(&matches);
if sopts.debugging_opts.debug_llvm {
unsafe { llvm::LLVMSetDebug(1); }
unsafe { llvm::LLVMRustSetDebug(1); }
}
let descriptions = diagnostics_registry();

View File

@ -112,8 +112,7 @@ fn main() {
cfg.flag(&flag);
}
cfg.file("../rustllvm/ExecutionEngineWrapper.cpp")
.file("../rustllvm/PassWrapper.cpp")
cfg.file("../rustllvm/PassWrapper.cpp")
.file("../rustllvm/RustWrapper.cpp")
.file("../rustllvm/ArchiveWrapper.cpp")
.cpp(true)

View File

@ -16,22 +16,29 @@ pub use self::Diagnostic::*;
use libc::{c_char, c_uint};
use std::ptr;
use {DebugLocRef, DiagnosticInfoRef, TwineRef, ValueRef};
use {DiagnosticInfoRef, TwineRef, ValueRef};
use ffi::DebugLocRef;
#[derive(Copy, Clone)]
pub enum OptimizationDiagnosticKind {
OptimizationRemark,
OptimizationMissed,
OptimizationAnalysis,
OptimizationAnalysisFPCommute,
OptimizationAnalysisAliasing,
OptimizationFailure,
OptimizationRemarkOther,
}
impl OptimizationDiagnosticKind {
pub fn describe(self) -> &'static str {
match self {
OptimizationRemark => "remark",
OptimizationRemark |
OptimizationRemarkOther => "remark",
OptimizationMissed => "missed",
OptimizationAnalysis => "analysis",
OptimizationAnalysisFPCommute => "floating-point",
OptimizationAnalysisAliasing => "aliasing",
OptimizationFailure => "failure",
}
}
@ -58,11 +65,11 @@ impl OptimizationDiagnostic {
message: ptr::null_mut(),
};
super::LLVMUnpackOptimizationDiagnostic(di,
&mut opt.pass_name,
&mut opt.function,
&mut opt.debug_loc,
&mut opt.message);
super::LLVMRustUnpackOptimizationDiagnostic(di,
&mut opt.pass_name,
&mut opt.function,
&mut opt.debug_loc,
&mut opt.message);
opt
}
@ -84,10 +91,10 @@ impl InlineAsmDiagnostic {
instruction: ptr::null_mut(),
};
super::LLVMUnpackInlineAsmDiagnostic(di,
&mut opt.cookie,
&mut opt.message,
&mut opt.instruction);
super::LLVMRustUnpackInlineAsmDiagnostic(di,
&mut opt.cookie,
&mut opt.message,
&mut opt.instruction);
opt
}
@ -103,24 +110,39 @@ pub enum Diagnostic {
impl Diagnostic {
pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic {
let kind = super::LLVMGetDiagInfoKind(di);
use super::DiagnosticKind as Dk;
let kind = super::LLVMRustGetDiagInfoKind(di);
match kind {
super::DK_InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpack(di)),
super::DK_OptimizationRemark => {
Dk::OptimizationRemark => {
Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
}
super::DK_OptimizationRemarkMissed => {
Dk::OptimizationRemarkOther => {
Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
}
Dk::OptimizationRemarkMissed => {
Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
}
super::DK_OptimizationRemarkAnalysis => {
Dk::OptimizationRemarkAnalysis => {
Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
}
super::DK_OptimizationFailure => {
Dk::OptimizationRemarkAnalysisFPCommute => {
Optimization(OptimizationDiagnostic::unpack(
OptimizationAnalysisFPCommute, di))
}
Dk::OptimizationRemarkAnalysisAliasing => {
Optimization(OptimizationDiagnostic::unpack(
OptimizationAnalysisAliasing, di))
}
Dk::OptimizationFailure => {
Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
}

2068
src/librustc_llvm/ffi.rs Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -552,13 +552,13 @@ impl FnType {
pub fn apply_attrs_llfn(&self, llfn: ValueRef) {
let mut i = if self.ret.is_indirect() { 1 } else { 0 };
if !self.ret.is_ignore() {
self.ret.attrs.apply_llfn(i, llfn);
self.ret.attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
}
i += 1;
for arg in &self.args {
if !arg.is_ignore() {
if arg.pad.is_some() { i += 1; }
arg.attrs.apply_llfn(i, llfn);
arg.attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
i += 1;
}
}
@ -567,13 +567,13 @@ impl FnType {
pub fn apply_attrs_callsite(&self, callsite: ValueRef) {
let mut i = if self.ret.is_indirect() { 1 } else { 0 };
if !self.ret.is_ignore() {
self.ret.attrs.apply_callsite(i, callsite);
self.ret.attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
}
i += 1;
for arg in &self.args {
if !arg.is_ignore() {
if arg.pad.is_some() { i += 1; }
arg.attrs.apply_callsite(i, callsite);
arg.attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
i += 1;
}
}

View File

@ -83,8 +83,8 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
};
let dialect = match ia.dialect {
AsmDialect::Att => llvm::AD_ATT,
AsmDialect::Intel => llvm::AD_Intel
AsmDialect::Att => llvm::AsmDialect::Att,
AsmDialect::Intel => llvm::AsmDialect::Intel,
};
let asm = CString::new(ia.asm.as_bytes()).unwrap();

View File

@ -9,8 +9,8 @@
// except according to those terms.
//! Set and unset common attributes on LLVM values.
use libc::c_uint;
use llvm::{self, ValueRef};
use llvm::{self, Attribute, ValueRef};
use llvm::AttributePlace::Function;
pub use syntax::attr::InlineAttr;
use syntax::ast;
use context::CrateContext;
@ -20,14 +20,14 @@ use context::CrateContext;
pub fn inline(val: ValueRef, inline: InlineAttr) {
use self::InlineAttr::*;
match inline {
Hint => llvm::SetFunctionAttribute(val, llvm::Attribute::InlineHint),
Always => llvm::SetFunctionAttribute(val, llvm::Attribute::AlwaysInline),
Never => llvm::SetFunctionAttribute(val, llvm::Attribute::NoInline),
Hint => Attribute::InlineHint.apply_llfn(Function, val),
Always => Attribute::AlwaysInline.apply_llfn(Function, val),
Never => Attribute::NoInline.apply_llfn(Function, val),
None => {
let attr = llvm::Attribute::InlineHint |
llvm::Attribute::AlwaysInline |
llvm::Attribute::NoInline;
llvm::RemoveFunctionAttributes(val, attr)
let attr = Attribute::InlineHint |
Attribute::AlwaysInline |
Attribute::NoInline;
attr.unapply_llfn(Function, val)
},
};
}
@ -35,56 +35,37 @@ pub fn inline(val: ValueRef, inline: InlineAttr) {
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
#[inline]
pub fn emit_uwtable(val: ValueRef, emit: bool) {
if emit {
llvm::SetFunctionAttribute(val, llvm::Attribute::UWTable);
} else {
llvm::RemoveFunctionAttributes(val, llvm::Attribute::UWTable);
}
Attribute::UWTable.toggle_llfn(Function, val, emit);
}
/// Tell LLVM whether the function can or cannot unwind.
#[inline]
pub fn unwind(val: ValueRef, can_unwind: bool) {
if can_unwind {
llvm::RemoveFunctionAttributes(val, llvm::Attribute::NoUnwind);
} else {
llvm::SetFunctionAttribute(val, llvm::Attribute::NoUnwind);
}
Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
}
/// Tell LLVM whether it should optimise function for size.
#[inline]
#[allow(dead_code)] // possibly useful function
pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
if optimize {
llvm::SetFunctionAttribute(val, llvm::Attribute::OptimizeForSize);
} else {
llvm::RemoveFunctionAttributes(val, llvm::Attribute::OptimizeForSize);
}
Attribute::OptimizeForSize.toggle_llfn(Function, val, optimize);
}
/// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue.
#[inline]
pub fn naked(val: ValueRef, is_naked: bool) {
if is_naked {
llvm::SetFunctionAttribute(val, llvm::Attribute::Naked);
} else {
llvm::RemoveFunctionAttributes(val, llvm::Attribute::Naked);
}
Attribute::Naked.toggle_llfn(Function, val, is_naked);
}
pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) {
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
// parameter.
if ccx.sess().must_not_eliminate_frame_pointers() {
unsafe {
let attr = "no-frame-pointer-elim\0".as_ptr() as *const _;
let val = "true\0".as_ptr() as *const _;
llvm::LLVMAddFunctionAttrStringValue(llfn,
llvm::FunctionIndex as c_uint,
attr,
val);
}
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
"no-frame-pointer-elim\0",
"true\0")
}
}
@ -98,13 +79,12 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
for attr in attrs {
if attr.check_name("cold") {
llvm::Attributes::default().set(llvm::Attribute::Cold)
.apply_llfn(llvm::FunctionIndex as usize, llfn)
Attribute::Cold.apply_llfn(Function, llfn);
} else if attr.check_name("naked") {
naked(llfn, true);
} else if attr.check_name("allocator") {
llvm::Attributes::default().set(llvm::Attribute::NoAlias)
.apply_llfn(llvm::ReturnIndex as usize, llfn)
Attribute::NoAlias.apply_llfn(
llvm::AttributePlace::ReturnValue(), llfn);
} else if attr.check_name("unwind") {
unwind(llfn, true);
}

View File

@ -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()

View File

@ -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
@ -365,7 +365,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
cookie: c_uint) {
let HandlerFreeVars { cgcx, .. } = *(user as *const HandlerFreeVars);
let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
let msg = llvm::build_string(|s| llvm::LLVMRustWriteSMDiagnosticToString(diag, s))
.expect("non-UTF8 SMDiagnostic");
report_inline_asm(cgcx, &msg[..], cookie);
@ -421,7 +421,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
};
let fv = &fv as *const HandlerFreeVars as *mut c_void;
llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv);
llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
let module_name = Some(&mtrans.name[..]);
@ -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);

View File

@ -2347,8 +2347,9 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
let has_fixed_linkage = linkage_fixed_explicitly.contains(&name_cow);
if !is_referenced_somewhere && !is_reachable && !has_fixed_linkage {
llvm::SetLinkage(val, llvm::InternalLinkage);
llvm::SetDLLStorageClass(val, llvm::DefaultStorageClass);
llvm::LLVMSetLinkage(val, llvm::InternalLinkage);
llvm::LLVMSetDLLStorageClass(val,
llvm::DLLStorageClass::Default);
llvm::UnsetComdat(val);
}
}
@ -2393,7 +2394,7 @@ fn create_imps(cx: &CrateContextList) {
imp_name.as_ptr() as *const _);
let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
llvm::LLVMSetInitializer(imp, init);
llvm::SetLinkage(imp, llvm::ExternalLinkage);
llvm::LLVMSetLinkage(imp, llvm::ExternalLinkage);
}
}
}

View File

@ -12,7 +12,7 @@
#![allow(non_snake_case)]
use llvm;
use llvm::{AtomicBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
use llvm::{Opcode, IntPredicate, RealPredicate};
use llvm::{ValueRef, BasicBlockRef};
use common::*;
@ -1117,7 +1117,7 @@ pub fn AtomicCmpXchg(cx: Block, dst: ValueRef,
weak: llvm::Bool) -> ValueRef {
B(cx).atomic_cmpxchg(dst, cmp, src, order, failure_order, weak)
}
pub fn AtomicRMW(cx: Block, op: AtomicBinOp,
pub fn AtomicRMW(cx: Block, op: AtomicRmwBinOp,
dst: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
B(cx).atomic_rmw(op, dst, src, order)

View File

@ -11,7 +11,7 @@
#![allow(dead_code)] // FFI wrappers
use llvm;
use llvm::{AtomicBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
use llvm::{Opcode, IntPredicate, RealPredicate, False, OperandBundleDef};
use llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
use base;
@ -503,8 +503,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
unsafe {
let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
let align = llalign_of_pref(self.ccx, ty.element_type());
llvm::LLVMBuildAtomicLoad(self.llbuilder, ptr, noname(), order,
align as c_uint)
llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order,
align as c_uint)
}
}
@ -565,7 +565,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
unsafe {
let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
let align = llalign_of_pref(self.ccx, ty.element_type());
llvm::LLVMBuildAtomicStore(self.llbuilder, val, ptr, order, align as c_uint);
llvm::LLVMRustBuildAtomicStore(self.llbuilder, val, ptr, order, align as c_uint);
}
}
@ -840,8 +840,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
debug!("Asm Output Type: {:?}", output);
let fty = Type::func(&argtys[..], &output);
unsafe {
let v = llvm::LLVMInlineAsm(
fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint);
let v = llvm::LLVMRustInlineAsm(
fty.to_ref(), asm, cons, volatile, alignstack, dia);
self.call(v, inputs, None)
}
}
@ -1087,7 +1087,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
order, failure_order, weak)
}
}
pub fn atomic_rmw(&self, op: AtomicBinOp,
pub fn atomic_rmw(&self, op: AtomicRmwBinOp,
dst: ValueRef, src: ValueRef,
order: AtomicOrdering) -> ValueRef {
unsafe {
@ -1097,7 +1097,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) {
unsafe {
llvm::LLVMBuildAtomicFence(self.llbuilder, order, scope);
llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
}
}
}

View File

@ -249,11 +249,13 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
if !ccx.instances().borrow().contains_key(&instance) {
let llfn = get_or_create_closure_declaration(ccx, closure_def_id, closure_substs);
if ccx.sess().target.target.options.allows_weak_linkage {
llvm::SetLinkage(llfn, llvm::WeakODRLinkage);
llvm::SetUniqueComdat(ccx.llmod(), llfn);
} else {
llvm::SetLinkage(llfn, llvm::InternalLinkage);
unsafe {
if ccx.sess().target.target.options.allows_weak_linkage {
llvm::LLVMSetLinkage(llfn, llvm::WeakODRLinkage);
llvm::SetUniqueComdat(ccx.llmod(), llfn);
} else {
llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage);
}
}
// set an inline hint for all closures

View File

@ -980,7 +980,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
});
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
llvm::SetLinkage(g, llvm::InternalLinkage);
llvm::LLVMSetLinkage(g, llvm::InternalLinkage);
cx.const_cstr_cache().borrow_mut().insert(s, g);
g

View File

@ -10,7 +10,7 @@
use llvm;
use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
use llvm::{SetUnnamedAddr};
use llvm::{InternalLinkage, ValueRef, Bool, True};
use middle::const_qualif::ConstQualif;
use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, lookup_const_by_id, ErrKind};
@ -125,7 +125,7 @@ pub fn addr_of_mut(ccx: &CrateContext,
});
llvm::LLVMSetInitializer(gv, cv);
llvm::LLVMSetAlignment(gv, align);
SetLinkage(gv, InternalLinkage);
llvm::LLVMSetLinkage(gv, InternalLinkage);
SetUnnamedAddr(gv, true);
gv
}
@ -637,10 +637,10 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
hir::BiEq | hir::BiNe | hir::BiLt | hir::BiLe | hir::BiGt | hir::BiGe => {
if is_float {
let cmp = base::bin_op_to_fcmp_predicate(b.node);
ConstFCmp(cmp, te1, te2)
llvm::LLVMConstFCmp(cmp, te1, te2)
} else {
let cmp = base::bin_op_to_icmp_predicate(b.node, signed);
ConstICmp(cmp, te1, te2)
llvm::LLVMConstICmp(cmp, te1, te2)
}
},
} } // unsafe { match b.node {
@ -1072,7 +1072,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
unsafe {
// Declare a symbol `foo` with the desired linkage.
let g1 = declare::declare_global(ccx, &sym, llty2);
llvm::SetLinkage(g1, linkage);
llvm::LLVMSetLinkage(g1, linkage);
// Declare an internal global `extern_with_linkage_foo` which
// is initialized with the address of `foo`. If `foo` is
@ -1086,7 +1086,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
ccx.sess().span_fatal(span,
&format!("symbol `{}` is already defined", &sym))
});
llvm::SetLinkage(g2, llvm::InternalLinkage);
llvm::LLVMSetLinkage(g2, llvm::InternalLinkage);
llvm::LLVMSetInitializer(g2, g1);
g2
}
@ -1126,7 +1126,9 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
}
}
if ccx.use_dll_storage_attrs() {
llvm::SetDLLStorageClass(g, llvm::DLLImportStorageClass);
unsafe {
llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport);
}
}
g
};
@ -1182,7 +1184,7 @@ pub fn trans_static(ccx: &CrateContext,
let name_str_ref = CStr::from_ptr(llvm::LLVMGetValueName(datum.val));
let name_string = CString::new(name_str_ref.to_bytes()).unwrap();
llvm::LLVMSetValueName(datum.val, empty_string.as_ptr());
let new_g = llvm::LLVMGetOrInsertGlobal(
let new_g = llvm::LLVMRustGetOrInsertGlobal(
ccx.llmod(), name_string.as_ptr(), val_llty.to_ref());
// To avoid breaking any invariants, we leave around the old
// global for the moment; we'll replace all references to it

View File

@ -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) {

View File

@ -133,7 +133,7 @@ fn make_mir_scope(ccx: &CrateContext,
let loc = span_start(ccx, scope_data.span);
scopes[scope] = unsafe {
let file_metadata = file_metadata(ccx, &loc.file.name, &loc.file.abs_path);
llvm::LLVMDIBuilderCreateLexicalBlock(
llvm::LLVMRustDIBuilderCreateLexicalBlock(
DIB(ccx),
parent_scope,
file_metadata,
@ -156,7 +156,7 @@ fn with_new_scope<F>(cx: &CrateContext,
let parent_scope = scope_stack.last().unwrap().scope_metadata;
let scope_metadata = unsafe {
llvm::LLVMDIBuilderCreateLexicalBlock(
llvm::LLVMRustDIBuilderCreateLexicalBlock(
DIB(cx),
parent_scope,
file_metadata,
@ -272,7 +272,7 @@ fn walk_pattern(cx: &CrateContext,
let parent_scope = scope_stack.last().unwrap().scope_metadata;
let scope_metadata = unsafe {
llvm::LLVMDIBuilderCreateLexicalBlock(
llvm::LLVMRustDIBuilderCreateLexicalBlock(
DIB(cx),
parent_scope,
file_metadata,

View File

@ -77,7 +77,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents));
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
llvm::SetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
llvm::LLVMSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
// This should make sure that the whole section is not larger than
// the string it contains. Otherwise we get a warning from GDB.
llvm::LLVMSetAlignment(section_var, 1);

View File

@ -504,12 +504,12 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
};
let subrange = unsafe {
llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
};
let subscripts = create_DIArray(DIB(cx), &[subrange]);
let metadata = unsafe {
llvm::LLVMDIBuilderCreateArrayType(
llvm::LLVMRustDIBuilderCreateArrayType(
DIB(cx),
bytes_to_bits(array_size_in_bytes),
bytes_to_bits(element_type_align),
@ -612,7 +612,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
return MetadataCreationResult::new(
unsafe {
llvm::LLVMDIBuilderCreateSubroutineType(
llvm::LLVMRustDIBuilderCreateSubroutineType(
DIB(cx),
unknown_file_metadata(cx),
create_DIArray(DIB(cx), &signature_metadata[..]))
@ -885,8 +885,8 @@ fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str)
let file_name = CString::new(file_name).unwrap();
let work_dir = CString::new(work_dir).unwrap();
let file_metadata = unsafe {
llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
work_dir.as_ptr())
llvm::LLVMRustDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
work_dir.as_ptr())
};
let mut created_files = debug_context(cx).created_files.borrow_mut();
@ -916,7 +916,7 @@ pub fn scope_metadata(fcx: &FunctionContext,
pub fn diverging_type_metadata(cx: &CrateContext) -> DIType {
unsafe {
llvm::LLVMDIBuilderCreateBasicType(
llvm::LLVMRustDIBuilderCreateBasicType(
DIB(cx),
"!\0".as_ptr() as *const _,
bytes_to_bits(0),
@ -951,7 +951,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let (size, align) = size_and_align_of(cx, llvm_type);
let name = CString::new(name).unwrap();
let ty_metadata = unsafe {
llvm::LLVMDIBuilderCreateBasicType(
llvm::LLVMRustDIBuilderCreateBasicType(
DIB(cx),
name.as_ptr(),
bytes_to_bits(size),
@ -971,7 +971,7 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let name = compute_debuginfo_type_name(cx, pointer_type, false);
let name = CString::new(name).unwrap();
let ptr_metadata = unsafe {
llvm::LLVMDIBuilderCreatePointerType(
llvm::LLVMRustDIBuilderCreatePointerType(
DIB(cx),
pointee_type_metadata,
bytes_to_bits(pointer_size),
@ -1017,7 +1017,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext,
let flags = "\0";
let split_name = "\0";
return unsafe {
llvm::LLVMDIBuilderCreateCompileUnit(
llvm::LLVMRustDIBuilderCreateCompileUnit(
debug_context.builder,
DW_LANG_RUST,
compile_unit_name,
@ -1596,7 +1596,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let token = v.name.as_str();
let name = CString::new(token.as_bytes()).unwrap();
unsafe {
llvm::LLVMDIBuilderCreateEnumerator(
llvm::LLVMRustDIBuilderCreateEnumerator(
DIB(cx),
name.as_ptr(),
v.disr_val.to_u64_unchecked())
@ -1623,7 +1623,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let name = CString::new(discriminant_name.as_bytes()).unwrap();
let discriminant_type_metadata = unsafe {
llvm::LLVMDIBuilderCreateEnumerationType(
llvm::LLVMRustDIBuilderCreateEnumerationType(
DIB(cx),
containing_scope,
name.as_ptr(),
@ -1667,7 +1667,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let enum_name = CString::new(enum_name).unwrap();
let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
let enum_metadata = unsafe {
llvm::LLVMDIBuilderCreateUnionType(
llvm::LLVMRustDIBuilderCreateUnionType(
DIB(cx),
containing_scope,
enum_name.as_ptr(),
@ -1769,7 +1769,7 @@ fn set_members_of_composite_type(cx: &CrateContext,
let member_name = member_description.name.as_bytes();
let member_name = CString::new(member_name).unwrap();
unsafe {
llvm::LLVMDIBuilderCreateMemberType(
llvm::LLVMRustDIBuilderCreateMemberType(
DIB(cx),
composite_type_metadata,
member_name.as_ptr(),
@ -1786,13 +1786,14 @@ fn set_members_of_composite_type(cx: &CrateContext,
unsafe {
let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array);
llvm::LLVMRustDICompositeTypeSetTypeArray(
DIB(cx), composite_type_metadata, type_array);
}
}
// A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
// caching, does not add any fields to the struct. This can be done later with
// set_members_of_composite_type().
// A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
// any caching, does not add any fields to the struct. This can be done later
// with set_members_of_composite_type().
fn create_struct_stub(cx: &CrateContext,
struct_llvm_type: Type,
struct_type_name: &str,
@ -1807,12 +1808,12 @@ fn create_struct_stub(cx: &CrateContext,
let name = CString::new(struct_type_name).unwrap();
let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
let metadata_stub = unsafe {
// LLVMDIBuilderCreateStructType() wants an empty array. A null
// LLVMRustDIBuilderCreateStructType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
// later on in llvm/lib/IR/Value.cpp.
let empty_array = create_DIArray(DIB(cx), &[]);
llvm::LLVMDIBuilderCreateStructType(
llvm::LLVMRustDIBuilderCreateStructType(
DIB(cx),
containing_scope,
name.as_ptr(),
@ -1868,16 +1869,16 @@ pub fn create_global_var_metadata(cx: &CrateContext,
let var_name = CString::new(var_name).unwrap();
let linkage_name = CString::new(linkage_name).unwrap();
unsafe {
llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
var_scope,
var_name.as_ptr(),
linkage_name.as_ptr(),
file_metadata,
line_number,
type_metadata,
is_local_to_unit,
global,
ptr::null_mut());
llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
var_scope,
var_name.as_ptr(),
linkage_name.as_ptr(),
file_metadata,
line_number,
type_metadata,
is_local_to_unit,
global,
ptr::null_mut());
}
}
@ -1980,10 +1981,10 @@ pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
env_index);
let address_operations = unsafe {
[llvm::LLVMDIBuilderCreateOpDeref(),
llvm::LLVMDIBuilderCreateOpPlus(),
[llvm::LLVMRustDIBuilderCreateOpDeref(),
llvm::LLVMRustDIBuilderCreateOpPlus(),
byte_offset_of_var_in_env as i64,
llvm::LLVMDIBuilderCreateOpDeref()]
llvm::LLVMRustDIBuilderCreateOpDeref()]
};
let address_op_count = if captured_by_ref {
@ -2021,7 +2022,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let scope_metadata = scope_metadata(bcx.fcx, binding.id, binding.span);
let aops = unsafe {
[llvm::LLVMDIBuilderCreateOpDeref()]
[llvm::LLVMRustDIBuilderCreateOpDeref()]
};
// Regardless of the actual type (`T`) we're always passed the stack slot
// (alloca) for the binding. For ByRef bindings that's a `T*` but for ByMove

View File

@ -89,7 +89,7 @@ pub struct CrateDebugContext<'tcx> {
impl<'tcx> CrateDebugContext<'tcx> {
pub fn new(llmod: ModuleRef) -> CrateDebugContext<'tcx> {
debug!("CrateDebugContext::new");
let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
// DIBuilder inherits context from the module, so we'd better use the same one
let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
return CrateDebugContext {
@ -179,8 +179,8 @@ pub fn finalize(cx: &CrateContext) {
}
unsafe {
llvm::LLVMDIBuilderFinalize(DIB(cx));
llvm::LLVMDIBuilderDispose(DIB(cx));
llvm::LLVMRustDIBuilderFinalize(DIB(cx));
llvm::LLVMRustDIBuilderDispose(DIB(cx));
// Debuginfo generation in LLVM by default uses a higher
// version of dwarf than OS X currently understands. We can
// instruct LLVM to emit an older version of dwarf, however,
@ -252,7 +252,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let function_type_metadata = unsafe {
let fn_signature = get_function_signature(cx, sig, abi);
llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
};
// Find the enclosing function, in case this is a closure.
@ -286,7 +286,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let linkage_name = CString::new(linkage_name).unwrap();
let fn_metadata = unsafe {
llvm::LLVMDIBuilderCreateFunction(
llvm::LLVMRustDIBuilderCreateFunction(
DIB(cx),
containing_scope,
function_name.as_ptr(),
@ -390,7 +390,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
let name = CString::new(param.name.as_str().as_bytes()).unwrap();
unsafe {
llvm::LLVMDIBuilderCreateTemplateTypeParameter(
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
DIB(cx),
ptr::null_mut(),
name.as_ptr(),
@ -494,7 +494,7 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
(DirectVariable { alloca }, address_operations) |
(IndirectVariable {alloca, address_operations}, _) => {
let metadata = unsafe {
llvm::LLVMDIBuilderCreateVariable(
llvm::LLVMRustDIBuilderCreateVariable(
DIB(cx),
dwarf_tag,
scope_metadata,
@ -512,7 +512,7 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize()));
unsafe {
let debug_loc = llvm::LLVMGetCurrentDebugLocation(cx.raw_builder());
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd(
DIB(cx),
alloca,
metadata,

View File

@ -78,7 +78,7 @@ pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope {
};
let scope = unsafe {
llvm::LLVMDIBuilderCreateNameSpace(
llvm::LLVMRustDIBuilderCreateNameSpace(
DIB(ccx),
parent_scope,
namespace_name.as_ptr(),

View File

@ -206,7 +206,7 @@ pub fn set_debug_location(cx: &CrateContext,
debug!("setting debug location to {} {}", line, col);
unsafe {
llvm::LLVMDIBuilderCreateDebugLocation(
llvm::LLVMRustDIBuilderCreateDebugLocation(
debug_context(cx).llcontext,
line as c_uint,
col as c_uint,

View File

@ -40,7 +40,7 @@ pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
#[allow(non_snake_case)]
pub fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
return unsafe {
llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
};
}

View File

@ -20,6 +20,7 @@
//! * Use define_* family of methods when you might be defining the ValueRef.
//! * When in doubt, define.
use llvm::{self, ValueRef};
use llvm::AttributePlace::Function;
use rustc::ty;
use abi::{Abi, FnType};
use attributes;
@ -40,7 +41,7 @@ pub fn declare_global(ccx: &CrateContext, name: &str, ty: Type) -> llvm::ValueRe
bug!("name {:?} contains an interior null byte", name)
});
unsafe {
llvm::LLVMGetOrInsertGlobal(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
llvm::LLVMRustGetOrInsertGlobal(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
}
}
@ -55,7 +56,7 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
bug!("name {:?} contains an interior null byte", name)
});
let llfn = unsafe {
llvm::LLVMGetOrInsertFunction(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
llvm::LLVMRustGetOrInsertFunction(ccx.llmod(), namebuf.as_ptr(), ty.to_ref())
};
llvm::SetFunctionCallConv(llfn, callconv);
@ -65,16 +66,16 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
if ccx.tcx().sess.opts.cg.no_redzone
.unwrap_or(ccx.tcx().sess.target.target.options.disable_redzone) {
llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoRedZone)
llvm::Attribute::NoRedZone.apply_llfn(Function, llfn);
}
match ccx.tcx().sess.opts.cg.opt_level.as_ref().map(String::as_ref) {
Some("s") => {
llvm::SetFunctionAttribute(llfn, llvm::Attribute::OptimizeForSize);
llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
},
Some("z") => {
llvm::SetFunctionAttribute(llfn, llvm::Attribute::MinSize);
llvm::SetFunctionAttribute(llfn, llvm::Attribute::OptimizeForSize);
llvm::Attribute::MinSize.apply_llfn(Function, llfn);
llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
},
_ => {},
}
@ -111,7 +112,7 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx));
if sig.output == ty::FnDiverging {
llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoReturn);
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
}
if abi != Abi::Rust && abi != Abi::RustCall {
@ -162,7 +163,7 @@ pub fn define_internal_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
name: &str,
fn_type: ty::Ty<'tcx>) -> ValueRef {
let llfn = define_fn(ccx, name, fn_type);
llvm::SetLinkage(llfn, llvm::InternalLinkage);
unsafe { llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage) };
llfn
}
@ -173,7 +174,7 @@ pub fn get_declared_value(ccx: &CrateContext, name: &str) -> Option<ValueRef> {
let namebuf = CString::new(name).unwrap_or_else(|_|{
bug!("name {:?} contains an interior null byte", name)
});
let val = unsafe { llvm::LLVMGetNamedValue(ccx.llmod(), namebuf.as_ptr()) };
let val = unsafe { llvm::LLVMRustGetNamedValue(ccx.llmod(), namebuf.as_ptr()) };
if val.is_null() {
debug!("get_declared_value: {:?} value is null", name);
None

View File

@ -640,28 +640,30 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
// This requires that atomic intrinsics follow a specific naming pattern:
// "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
(_, name) if name.starts_with("atomic_") => {
use llvm::AtomicOrdering::*;
let split: Vec<&str> = name.split('_').collect();
let is_cxchg = split[1] == "cxchg" || split[1] == "cxchgweak";
let (order, failorder) = match split.len() {
2 => (llvm::SequentiallyConsistent, llvm::SequentiallyConsistent),
2 => (SequentiallyConsistent, SequentiallyConsistent),
3 => match split[2] {
"unordered" => (llvm::Unordered, llvm::Unordered),
"relaxed" => (llvm::Monotonic, llvm::Monotonic),
"acq" => (llvm::Acquire, llvm::Acquire),
"rel" => (llvm::Release, llvm::Monotonic),
"acqrel" => (llvm::AcquireRelease, llvm::Acquire),
"unordered" => (Unordered, Unordered),
"relaxed" => (Monotonic, Monotonic),
"acq" => (Acquire, Acquire),
"rel" => (Release, Monotonic),
"acqrel" => (AcquireRelease, Acquire),
"failrelaxed" if is_cxchg =>
(llvm::SequentiallyConsistent, llvm::Monotonic),
(SequentiallyConsistent, Monotonic),
"failacq" if is_cxchg =>
(llvm::SequentiallyConsistent, llvm::Acquire),
(SequentiallyConsistent, Acquire),
_ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
},
4 => match (split[2], split[3]) {
("acq", "failrelaxed") if is_cxchg =>
(llvm::Acquire, llvm::Monotonic),
(Acquire, Monotonic),
("acqrel", "failrelaxed") if is_cxchg =>
(llvm::AcquireRelease, llvm::Monotonic),
(AcquireRelease, Monotonic),
_ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
},
_ => ccx.sess().fatal("Atomic intrinsic not in correct format"),
@ -714,12 +716,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
"fence" => {
AtomicFence(bcx, order, llvm::CrossThread);
AtomicFence(bcx, order, llvm::SynchronizationScope::CrossThread);
C_nil(ccx)
}
"singlethreadfence" => {
AtomicFence(bcx, order, llvm::SingleThread);
AtomicFence(bcx, order, llvm::SynchronizationScope::SingleThread);
C_nil(ccx)
}

View File

@ -824,11 +824,11 @@ pub fn const_scalar_binop(op: mir::BinOp,
mir::BinOp::Gt | mir::BinOp::Ge => {
if is_float {
let cmp = base::bin_op_to_fcmp_predicate(op.to_hir_binop());
llvm::ConstFCmp(cmp, lhs, rhs)
llvm::LLVMConstFCmp(cmp, lhs, rhs)
} else {
let cmp = base::bin_op_to_icmp_predicate(op.to_hir_binop(),
signed);
llvm::ConstICmp(cmp, lhs, rhs)
llvm::LLVMConstICmp(cmp, lhs, rhs)
}
}
}

View File

@ -324,8 +324,8 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
machine::llelement_offset(bcx.ccx(), lltuplety, i);
let ops = unsafe {
[llvm::LLVMDIBuilderCreateOpDeref(),
llvm::LLVMDIBuilderCreateOpPlus(),
[llvm::LLVMRustDIBuilderCreateOpDeref(),
llvm::LLVMRustDIBuilderCreateOpPlus(),
byte_offset_of_var_in_tuple as i64]
};
@ -450,10 +450,10 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
machine::llelement_offset(bcx.ccx(), llclosurety, i);
let ops = unsafe {
[llvm::LLVMDIBuilderCreateOpDeref(),
llvm::LLVMDIBuilderCreateOpPlus(),
[llvm::LLVMRustDIBuilderCreateOpDeref(),
llvm::LLVMRustDIBuilderCreateOpPlus(),
byte_offset_of_var_in_env as i64,
llvm::LLVMDIBuilderCreateOpDeref()]
llvm::LLVMRustDIBuilderCreateOpDeref()]
};
// The environment and the capture can each be indirect.

View File

@ -125,7 +125,9 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
if ccx.shared().translation_items().borrow().contains(&trans_item) {
attributes::from_fn_attrs(ccx, attrs, lldecl);
llvm::SetLinkage(lldecl, llvm::ExternalLinkage);
unsafe {
llvm::LLVMSetLinkage(lldecl, llvm::ExternalLinkage);
}
} else {
// FIXME: #34151
// Normally, getting here would indicate a bug in trans::collector,

View File

@ -208,7 +208,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
&format!("symbol `{}` is already defined", symbol_name))
});
llvm::SetLinkage(g, linkage);
unsafe { llvm::LLVMSetLinkage(g, linkage) };
}
item => bug!("predefine_static: expected static, found {:?}", item)
@ -250,7 +250,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
ref attrs, node: hir::ImplItemKind::Method(..), ..
}) => {
let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
llvm::SetLinkage(lldecl, linkage);
unsafe { llvm::LLVMSetLinkage(lldecl, linkage) };
base::set_link_section(ccx, lldecl, attrs);
if linkage == llvm::LinkOnceODRLinkage ||
linkage == llvm::WeakODRLinkage {
@ -287,7 +287,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
assert!(declare::get_defined_value(ccx, symbol_name).is_none());
let llfn = declare::declare_cfn(ccx, symbol_name, llfnty);
llvm::SetLinkage(llfn, linkage);
unsafe { llvm::LLVMSetLinkage(llfn, linkage) };
if linkage == llvm::LinkOnceODRLinkage ||
linkage == llvm::WeakODRLinkage {
llvm::SetUniqueComdat(ccx.llmod(), llfn);

View File

@ -36,7 +36,7 @@ pub struct Type {
impl fmt::Debug for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&llvm::build_string(|s| unsafe {
llvm::LLVMWriteTypeToString(self.to_ref(), s);
llvm::LLVMRustWriteTypeToString(self.to_ref(), s);
}).expect("non-UTF8 type description from LLVM"))
}
}
@ -72,7 +72,7 @@ impl Type {
}
pub fn metadata(ccx: &CrateContext) -> Type {
ty!(llvm::LLVMMetadataTypeInContext(ccx.llcx()))
ty!(llvm::LLVMRustMetadataTypeInContext(ccx.llcx()))
}
pub fn i1(ccx: &CrateContext) -> Type {
@ -208,7 +208,7 @@ impl Type {
pub fn kind(&self) -> TypeKind {
unsafe {
llvm::LLVMGetTypeKind(self.to_ref())
llvm::LLVMRustGetTypeKind(self.to_ref())
}
}

View File

@ -23,7 +23,7 @@ pub struct Value(pub ValueRef);
impl fmt::Debug for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&llvm::build_string(|s| unsafe {
llvm::LLVMWriteValueToString(self.0, s);
llvm::LLVMRustWriteValueToString(self.0, s);
}).expect("nun-UTF8 value description from LLVM"))
}
}

View File

@ -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:
llvm_unreachable("Bad ArchiveKind.");
}
}
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;
}

View File

@ -1,111 +0,0 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// 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.
#include "rustllvm.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
using namespace llvm;
using namespace llvm::sys;
using namespace llvm::object;
class RustJITMemoryManager : public SectionMemoryManager
{
typedef SectionMemoryManager Base;
public:
RustJITMemoryManager() {}
uint64_t getSymbolAddress(const std::string &Name) override
{
return Base::getSymbolAddress(Name);
}
};
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)
extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
{
std::string err;
DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err);
if (!lib.isValid())
LLVMRustSetLastError(err.c_str());
return lib.isValid();
}
// Calls LLVMAddModule;
// exists for consistency with LLVMExecutionEngineRemoveModule
extern "C" void LLVMExecutionEngineAddModule(
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
{
#ifdef _WIN32
// On Windows, MCJIT must generate ELF objects
std::string target = getProcessTriple();
target += "-elf";
target = Triple::normalize(target);
unwrap(mref)->setTargetTriple(target);
#endif
LLVMAddModule(eeref, mref);
}
// LLVMRemoveModule exists in LLVM's C bindings,
// but it requires pointless parameters
extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
{
ExecutionEngine *ee = unwrap(eeref);
Module *m = unwrap(mref);
return ee->removeModule(m);
}
extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
{
// These are necessary for code generation to work properly.
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
#ifdef _WIN32
// On Windows, MCJIT must generate ELF objects
std::string target = getProcessTriple();
target += "-elf";
target = Triple::normalize(target);
unwrap(mod)->setTargetTriple(target);
#endif
std::string error_str;
TargetOptions options;
RustJITMemoryManager *mm = new RustJITMemoryManager;
ExecutionEngine *ee =
EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
.setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm))
.setEngineKind(EngineKind::JIT)
.setErrorStr(&error_str)
.setTargetOptions(options)
.create();
if (!ee)
LLVMRustSetLastError(error_str.c_str());
return wrap(ee);
}
extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref)
{
ExecutionEngine *ee = unwrap(eeref);
ee->finalizeObject();
}

View File

@ -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:
llvm_unreachable("Bad CodeModel.");
}
}
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:
llvm_unreachable("Bad CodeGenOptLevel.");
}
}
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:
llvm_unreachable("Bad FileType.");
}
}
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

View File

@ -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.

View File

@ -13,6 +13,7 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/CallSite.h"
@ -27,6 +28,30 @@ using namespace llvm;
using namespace llvm::sys;
using namespace llvm::object;
// LLVMAtomicOrdering is already an enum - don't create another
// one.
static AtomicOrdering from_rust(LLVMAtomicOrdering Ordering) {
switch (Ordering) {
case LLVMAtomicOrderingNotAtomic:
return AtomicOrdering::NotAtomic;
case LLVMAtomicOrderingUnordered:
return AtomicOrdering::Unordered;
case LLVMAtomicOrderingMonotonic:
return AtomicOrdering::Monotonic;
case LLVMAtomicOrderingAcquire:
return AtomicOrdering::Acquire;
case LLVMAtomicOrderingRelease:
return AtomicOrdering::Release;
case LLVMAtomicOrderingAcquireRelease:
return AtomicOrdering::AcquireRelease;
case LLVMAtomicOrderingSequentiallyConsistent:
return AtomicOrdering::SequentiallyConsistent;
}
llvm_unreachable("Invalid LLVMAtomicOrdering value!");
}
static char *LastError;
extern "C" LLVMMemoryBufferRef
@ -57,45 +82,30 @@ LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
unwrap(M)->setTargetTriple(Triple::normalize(triple));
}
extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
LLVMBool SignExtend) {
return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
}
extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
unsigned N_hi,
unsigned N_lo,
LLVMBool SignExtend) {
unsigned long long N = N_hi;
N <<= 32;
N |= N_lo;
return LLVMConstInt(IntTy, N, SignExtend);
}
extern "C" void LLVMRustPrintPassTimings() {
raw_fd_ostream OS (2, false); // stderr.
TimerGroup::printAll(OS);
}
extern "C" LLVMValueRef LLVMGetNamedValue(LLVMModuleRef M,
const char* Name) {
extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
const char* Name) {
return wrap(unwrap(M)->getNamedValue(Name));
}
extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
const char* Name,
LLVMTypeRef FunctionTy) {
extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
const char* Name,
LLVMTypeRef FunctionTy) {
return wrap(unwrap(M)->getOrInsertFunction(Name,
unwrap<FunctionType>(FunctionTy)));
}
extern "C" LLVMValueRef LLVMGetOrInsertGlobal(LLVMModuleRef M,
const char* Name,
LLVMTypeRef Ty) {
extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
const char* Name,
LLVMTypeRef Ty) {
return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
}
extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
return wrap(Type::getMetadataTy(*unwrap(C)));
}
@ -110,7 +120,10 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index,
}
extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned idx, uint64_t b) {
extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
unsigned idx,
uint64_t b)
{
CallSite Call = CallSite(unwrap<Instruction>(Instr));
AttrBuilder B;
B.addDereferenceableAttr(b);
@ -120,38 +133,50 @@ extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned
idx, B)));
}
extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index,
uint64_t Val) {
extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
unsigned index,
uint64_t Val)
{
Function *A = unwrap<Function>(Fn);
AttrBuilder B;
B.addRawValue(Val);
A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
}
extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn, unsigned index, uint64_t bytes) {
extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn,
unsigned index,
uint64_t bytes)
{
Function *A = unwrap<Function>(Fn);
AttrBuilder B;
B.addDereferenceableAttr(bytes);
A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
}
extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) {
extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn,
unsigned index,
const char *Name)
{
Function *F = unwrap<Function>(Fn);
AttrBuilder B;
B.addAttribute(Name);
F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
}
extern "C" void LLVMAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned index,
const char *Name,
const char *Value) {
extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
unsigned index,
const char *Name,
const char *Value) {
Function *F = unwrap<Function>(Fn);
AttrBuilder B;
B.addAttribute(Name, Value);
F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
}
extern "C" void LLVMRemoveFunctionAttributes(LLVMValueRef Fn, unsigned index, uint64_t Val) {
extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
unsigned index,
uint64_t Val)
{
Function *A = unwrap<Function>(Fn);
const AttributeSet PAL = A->getAttributes();
AttrBuilder B(Val);
@ -161,7 +186,10 @@ extern "C" void LLVMRemoveFunctionAttributes(LLVMValueRef Fn, unsigned index, ui
A->setAttributes(PALnew);
}
extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, unsigned index, const char *Name) {
extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn,
unsigned index,
const char *Name)
{
Function *f = unwrap<Function>(fn);
LLVMContext &C = f->getContext();
AttrBuilder B;
@ -181,24 +209,24 @@ extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
}
}
extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
LLVMValueRef source,
const char* Name,
AtomicOrdering order,
unsigned alignment) {
extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B,
LLVMValueRef source,
const char* Name,
LLVMAtomicOrdering order,
unsigned alignment) {
LoadInst* li = new LoadInst(unwrap(source),0);
li->setAtomic(order);
li->setAtomic(from_rust(order));
li->setAlignment(alignment);
return wrap(unwrap(B)->Insert(li, Name));
}
extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
LLVMValueRef val,
LLVMValueRef target,
AtomicOrdering order,
unsigned alignment) {
extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
LLVMValueRef val,
LLVMValueRef target,
LLVMAtomicOrdering order,
unsigned alignment) {
StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
si->setAtomic(order);
si->setAtomic(from_rust(order));
si->setAlignment(alignment);
return wrap(unwrap(B)->Insert(si));
}
@ -207,54 +235,96 @@ extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B,
LLVMValueRef target,
LLVMValueRef old,
LLVMValueRef source,
AtomicOrdering order,
AtomicOrdering failure_order,
LLVMAtomicOrdering order,
LLVMAtomicOrdering failure_order,
LLVMBool weak) {
AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(unwrap(target),
unwrap(old),
unwrap(source),
order,
failure_order);
AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(
unwrap(target),
unwrap(old),
unwrap(source),
from_rust(order),
from_rust(failure_order));
acxi->setWeak(weak);
return wrap(acxi);
}
extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B,
AtomicOrdering order,
SynchronizationScope scope) {
return wrap(unwrap(B)->CreateFence(order, scope));
enum class LLVMRustSynchronizationScope {
Other,
SingleThread,
CrossThread,
};
static SynchronizationScope
from_rust(LLVMRustSynchronizationScope scope)
{
switch (scope) {
case LLVMRustSynchronizationScope::SingleThread:
return SingleThread;
case LLVMRustSynchronizationScope::CrossThread:
return CrossThread;
default:
llvm_unreachable("bad SynchronizationScope.");
}
}
extern "C" void LLVMSetDebug(int Enabled) {
extern "C" LLVMValueRef LLVMRustBuildAtomicFence(
LLVMBuilderRef B,
LLVMAtomicOrdering order,
LLVMRustSynchronizationScope scope)
{
return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope)));
}
extern "C" void LLVMRustSetDebug(int Enabled) {
#ifndef NDEBUG
DebugFlag = Enabled;
#endif
}
extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
char *AsmString,
char *Constraints,
LLVMBool HasSideEffects,
LLVMBool IsAlignStack,
unsigned Dialect) {
return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
Constraints, HasSideEffects,
IsAlignStack, (InlineAsm::AsmDialect) Dialect));
enum class LLVMRustAsmDialect {
Other,
Att,
Intel,
};
static InlineAsm::AsmDialect
from_rust(LLVMRustAsmDialect dialect)
{
switch (dialect) {
case LLVMRustAsmDialect::Att:
return InlineAsm::AD_ATT;
case LLVMRustAsmDialect::Intel:
return InlineAsm::AD_Intel;
default:
llvm_unreachable("bad AsmDialect.");
}
}
typedef DIBuilder* DIBuilderRef;
extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty,
char *AsmString,
char *Constraints,
LLVMBool HasSideEffects,
LLVMBool IsAlignStack,
LLVMRustAsmDialect Dialect) {
return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
Constraints, HasSideEffects,
IsAlignStack, from_rust(Dialect)));
}
typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
typedef DIBuilder* LLVMRustDIBuilderRef;
typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
namespace llvm {
DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
inline Metadata **unwrap(LLVMMetadataRef *Vals) {
inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
return reinterpret_cast<Metadata**>(Vals);
}
}
template<typename DIT>
DIT* unwrapDIptr(LLVMMetadataRef ref) {
DIT* unwrapDIptr(LLVMRustMetadataRef ref) {
return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
}
@ -266,11 +336,11 @@ extern "C" uint32_t LLVMRustDebugMetadataVersion() {
return DEBUG_METADATA_VERSION;
}
extern "C" uint32_t LLVMVersionMinor() {
extern "C" uint32_t LLVMRustVersionMinor() {
return LLVM_VERSION_MINOR;
}
extern "C" uint32_t LLVMVersionMajor() {
extern "C" uint32_t LLVMRustVersionMajor() {
return LLVM_VERSION_MAJOR;
}
@ -280,20 +350,20 @@ extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
unwrap(M)->addModuleFlag(Module::Warning, name, value);
}
extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
return new DIBuilder(*unwrap(M));
}
extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
delete Builder;
}
extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
Builder->finalize();
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
LLVMRustDIBuilderRef Builder,
unsigned Lang,
const char* File,
const char* Dir,
@ -312,17 +382,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
SplitName));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateFile(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile(
LLVMRustDIBuilderRef Builder,
const char* Filename,
const char* Directory) {
return wrap(Builder->createFile(Filename, Directory));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
DIBuilderRef Builder,
LLVMMetadataRef File,
LLVMMetadataRef ParameterTypes) {
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef File,
LLVMRustMetadataRef ParameterTypes) {
return wrap(Builder->createSubroutineType(
#if LLVM_VERSION_MINOR == 7
unwrapDI<DIFile>(File),
@ -330,22 +400,22 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateSubroutineType(
DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
const char* Name,
const char* LinkageName,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNo,
LLVMMetadataRef Ty,
LLVMRustMetadataRef Ty,
bool isLocalToUnit,
bool isDefinition,
unsigned ScopeLine,
unsigned Flags,
bool isOptimized,
LLVMValueRef Fn,
LLVMMetadataRef TParam,
LLVMMetadataRef Decl) {
LLVMRustMetadataRef TParam,
LLVMRustMetadataRef Decl) {
#if LLVM_VERSION_MINOR >= 8
DITemplateParameterArray TParams =
DITemplateParameterArray(unwrap<MDTuple>(TParam));
@ -370,8 +440,8 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateFunction(
#endif
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType(
LLVMRustDIBuilderRef Builder,
const char* Name,
uint64_t SizeInBits,
uint64_t AlignInBits,
@ -381,9 +451,9 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateBasicType(
AlignInBits, Encoding));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
DIBuilderRef Builder,
LLVMMetadataRef PointeeTy,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef PointeeTy,
uint64_t SizeInBits,
uint64_t AlignInBits,
const char* Name) {
@ -391,19 +461,19 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreatePointerType(
unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
const char* Name,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
unsigned Flags,
LLVMMetadataRef DerivedFrom,
LLVMMetadataRef Elements,
LLVMRustMetadataRef DerivedFrom,
LLVMRustMetadataRef Elements,
unsigned RunTimeLang,
LLVMMetadataRef VTableHolder,
LLVMRustMetadataRef VTableHolder,
const char *UniqueId) {
return wrap(Builder->createStructType(
unwrapDI<DIDescriptor>(Scope),
@ -421,17 +491,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
const char* Name,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNo,
uint64_t SizeInBits,
uint64_t AlignInBits,
uint64_t OffsetInBits,
unsigned Flags,
LLVMMetadataRef Ty) {
LLVMRustMetadataRef Ty) {
return wrap(Builder->createMemberType(
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File), LineNo,
@ -439,10 +509,10 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateMemberType(
unwrapDI<DIType>(Ty)));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
LLVMMetadataRef File,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
LLVMRustMetadataRef File,
unsigned Line,
unsigned Col) {
return wrap(Builder->createLexicalBlock(
@ -451,17 +521,17 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
DIBuilderRef Builder,
LLVMMetadataRef Context,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Context,
const char* Name,
const char* LinkageName,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNo,
LLVMMetadataRef Ty,
LLVMRustMetadataRef Ty,
bool isLocalToUnit,
LLVMValueRef Val,
LLVMMetadataRef Decl = NULL) {
LLVMRustMetadataRef Decl = NULL) {
return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
Name,
LinkageName,
@ -473,14 +543,14 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStaticVariable(
unwrapDIptr<MDNode>(Decl)));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
LLVMRustDIBuilderRef Builder,
unsigned Tag,
LLVMMetadataRef Scope,
LLVMRustMetadataRef Scope,
const char* Name,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNo,
LLVMMetadataRef Ty,
LLVMRustMetadataRef Ty,
bool AlwaysPreserve,
unsigned Flags,
int64_t* AddrOps,
@ -509,50 +579,50 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
#endif
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateArrayType(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType(
LLVMRustDIBuilderRef Builder,
uint64_t Size,
uint64_t AlignInBits,
LLVMMetadataRef Ty,
LLVMMetadataRef Subscripts) {
LLVMRustMetadataRef Ty,
LLVMRustMetadataRef Subscripts) {
return wrap(Builder->createArrayType(Size, AlignInBits,
unwrapDI<DIType>(Ty),
DINodeArray(unwrapDI<MDTuple>(Subscripts))
));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateVectorType(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType(
LLVMRustDIBuilderRef Builder,
uint64_t Size,
uint64_t AlignInBits,
LLVMMetadataRef Ty,
LLVMMetadataRef Subscripts) {
LLVMRustMetadataRef Ty,
LLVMRustMetadataRef Subscripts) {
return wrap(Builder->createVectorType(Size, AlignInBits,
unwrapDI<DIType>(Ty),
DINodeArray(unwrapDI<MDTuple>(Subscripts))
));
}
extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(
LLVMRustDIBuilderRef Builder,
int64_t Lo,
int64_t Count) {
return wrap(Builder->getOrCreateSubrange(Lo, Count));
}
extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
DIBuilderRef Builder,
LLVMMetadataRef* Ptr,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef* Ptr,
unsigned Count) {
Metadata **DataValue = unwrap(Ptr);
return wrap(Builder->getOrCreateArray(
ArrayRef<Metadata*>(DataValue, Count)).get());
}
extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
DIBuilderRef Builder,
extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
LLVMRustDIBuilderRef Builder,
LLVMValueRef Val,
LLVMMetadataRef VarInfo,
LLVMRustMetadataRef VarInfo,
int64_t* AddrOps,
unsigned AddrOpsCount,
LLVMValueRef DL,
@ -566,10 +636,10 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
unwrap(InsertAtEnd)));
}
extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
DIBuilderRef Builder,
extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareBefore(
LLVMRustDIBuilderRef Builder,
LLVMValueRef Val,
LLVMMetadataRef VarInfo,
LLVMRustMetadataRef VarInfo,
int64_t* AddrOps,
unsigned AddrOpsCount,
LLVMValueRef DL,
@ -583,24 +653,24 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
unwrap<Instruction>(InsertBefore)));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerator(
DIBuilderRef Builder,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator(
LLVMRustDIBuilderRef Builder,
const char* Name,
uint64_t Val)
{
return wrap(Builder->createEnumerator(Name, Val));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
const char* Name,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
LLVMMetadataRef Elements,
LLVMMetadataRef ClassType)
LLVMRustMetadataRef Elements,
LLVMRustMetadataRef ClassType)
{
return wrap(Builder->createEnumerationType(
unwrapDI<DIDescriptor>(Scope),
@ -613,16 +683,16 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
unwrapDI<DIType>(ClassType)));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
const char* Name,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
unsigned Flags,
LLVMMetadataRef Elements,
LLVMRustMetadataRef Elements,
unsigned RunTimeLang,
const char* UniqueId)
{
@ -640,12 +710,12 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
));
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
const char* Name,
LLVMMetadataRef Ty,
LLVMMetadataRef File,
LLVMRustMetadataRef Ty,
LLVMRustMetadataRef File,
unsigned LineNo,
unsigned ColumnNo)
{
@ -656,21 +726,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
));
}
extern "C" int64_t LLVMDIBuilderCreateOpDeref()
{
return dwarf::DW_OP_deref;
}
extern "C" int64_t LLVMDIBuilderCreateOpPlus()
{
return dwarf::DW_OP_plus;
}
extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
DIBuilderRef Builder,
LLVMMetadataRef Scope,
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef Scope,
const char* Name,
LLVMMetadataRef File,
LLVMRustMetadataRef File,
unsigned LineNo)
{
return wrap(Builder->createNameSpace(
@ -680,22 +740,22 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateNameSpace(
LineNo));
}
extern "C" void LLVMDICompositeTypeSetTypeArray(
DIBuilderRef Builder,
LLVMMetadataRef CompositeType,
LLVMMetadataRef TypeArray)
extern "C" void LLVMRustDICompositeTypeSetTypeArray(
LLVMRustDIBuilderRef Builder,
LLVMRustMetadataRef CompositeType,
LLVMRustMetadataRef TypeArray)
{
DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation(
LLVMContextRef Context,
unsigned Line,
unsigned Column,
LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt) {
LLVMRustMetadataRef Scope,
LLVMRustMetadataRef InlinedAt)
{
LLVMContext& context = *unwrap(Context);
DebugLoc debug_loc = DebugLoc::get(Line,
@ -706,12 +766,22 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateDebugLocation(
return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
}
extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
{
return dwarf::DW_OP_deref;
}
extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
{
return dwarf::DW_OP_plus;
}
extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
raw_rust_string_ostream os(str);
unwrap<llvm::Type>(Type)->print(os);
}
extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) {
raw_rust_string_ostream os(str);
os << "(";
unwrap<llvm::Value>(Value)->getType()->print(os);
@ -746,13 +816,6 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
return true;
}
extern "C" void
LLVMRustSetDLLStorageClass(LLVMValueRef Value,
GlobalValue::DLLStorageClassTypes Class) {
GlobalValue *V = unwrap<GlobalValue>(Value);
V->setDLLStorageClass(Class);
}
// Note that the two following functions look quite similar to the
// LLVMGetSectionName function. Sadly, it appears that this function only
// returns a char* pointer, which isn't guaranteed to be null-terminated. The
@ -768,7 +831,7 @@ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
return reinterpret_cast<section_iterator*>(SI);
}
extern "C" int
extern "C" size_t
LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
StringRef ret;
if (std::error_code ec = (*unwrap(SI))->getName(ret))
@ -787,13 +850,13 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
extern "C" void
LLVMWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
raw_rust_string_ostream os(str);
unwrap(T)->print(os);
}
extern "C" void
LLVMUnpackOptimizationDiagnostic(
LLVMRustUnpackOptimizationDiagnostic(
LLVMDiagnosticInfoRef di,
const char **pass_name_out,
LLVMValueRef *function_out,
@ -811,7 +874,7 @@ LLVMUnpackOptimizationDiagnostic(
}
extern "C" void
LLVMUnpackInlineAsmDiagnostic(
LLVMRustUnpackInlineAsmDiagnostic(
LLVMDiagnosticInfoRef di,
unsigned *cookie_out,
LLVMTwineRef *message_out,
@ -826,17 +889,111 @@ LLVMUnpackInlineAsmDiagnostic(
*instruction_out = wrap(ia->getInstruction());
}
extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
raw_rust_string_ostream os(str);
DiagnosticPrinterRawOStream dp(os);
unwrap(di)->print(dp);
}
extern "C" int LLVMGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
return unwrap(di)->getKind();
enum class LLVMRustDiagnosticKind {
Other,
InlineAsm,
StackSize,
DebugMetadataVersion,
SampleProfile,
OptimizationRemark,
OptimizationRemarkMissed,
OptimizationRemarkAnalysis,
OptimizationRemarkAnalysisFPCommute,
OptimizationRemarkAnalysisAliasing,
OptimizationRemarkOther,
OptimizationFailure,
};
static LLVMRustDiagnosticKind
to_rust(DiagnosticKind kind)
{
switch (kind) {
case DK_InlineAsm:
return LLVMRustDiagnosticKind::InlineAsm;
case DK_StackSize:
return LLVMRustDiagnosticKind::StackSize;
case DK_DebugMetadataVersion:
return LLVMRustDiagnosticKind::DebugMetadataVersion;
case DK_SampleProfile:
return LLVMRustDiagnosticKind::SampleProfile;
case DK_OptimizationRemark:
return LLVMRustDiagnosticKind::OptimizationRemark;
case DK_OptimizationRemarkMissed:
return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
case DK_OptimizationRemarkAnalysis:
return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
#if LLVM_VERSION_MINOR >= 8
case DK_OptimizationRemarkAnalysisFPCommute:
return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
case DK_OptimizationRemarkAnalysisAliasing:
return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
#endif
default:
#if LLVM_VERSION_MINOR >= 9
return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ?
LLVMRustDiagnosticKind::OptimizationRemarkOther :
LLVMRustDiagnosticKind::Other;
#else
return LLVMRustDiagnosticKind::Other;
#endif
}
}
extern "C" void LLVMWriteDebugLocToString(
extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
return to_rust((DiagnosticKind) unwrap(di)->getKind());
}
// This is kept distinct from LLVMGetTypeKind, because when
// a new type kind is added, the Rust-side enum must be
// updated or UB will result.
extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
switch (unwrap(Ty)->getTypeID()) {
case Type::VoidTyID:
return LLVMVoidTypeKind;
case Type::HalfTyID:
return LLVMHalfTypeKind;
case Type::FloatTyID:
return LLVMFloatTypeKind;
case Type::DoubleTyID:
return LLVMDoubleTypeKind;
case Type::X86_FP80TyID:
return LLVMX86_FP80TypeKind;
case Type::FP128TyID:
return LLVMFP128TypeKind;
case Type::PPC_FP128TyID:
return LLVMPPC_FP128TypeKind;
case Type::LabelTyID:
return LLVMLabelTypeKind;
case Type::MetadataTyID:
return LLVMMetadataTypeKind;
case Type::IntegerTyID:
return LLVMIntegerTypeKind;
case Type::FunctionTyID:
return LLVMFunctionTypeKind;
case Type::StructTyID:
return LLVMStructTypeKind;
case Type::ArrayTyID:
return LLVMArrayTypeKind;
case Type::PointerTyID:
return LLVMPointerTypeKind;
case Type::VectorTyID:
return LLVMVectorTypeKind;
case Type::X86_MMXTyID:
return LLVMX86_MMXTypeKind;
#if LLVM_VERSION_MINOR >= 8
case Type::TokenTyID:
return LLVMTokenTypeKind;
#endif
}
llvm_unreachable("Unhandled TypeID.");
}
extern "C" void LLVMRustWriteDebugLocToString(
LLVMContextRef C,
LLVMDebugLocRef dl,
RustStringRef str)
@ -847,7 +1004,7 @@ extern "C" void LLVMWriteDebugLocToString(
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
extern "C" void LLVMSetInlineAsmDiagnosticHandler(
extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
LLVMContextRef C,
LLVMContext::InlineAsmDiagHandlerTy H,
void *CX)
@ -855,7 +1012,8 @@ extern "C" void LLVMSetInlineAsmDiagnosticHandler(
unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
}
extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) {
extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d,
RustStringRef str) {
raw_rust_string_ostream os(str);
unwrap(d)->print("", os);
}

View File

@ -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;