From 730400167ad2ce88bb48af3f36f3443ea4493d50 Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Thu, 24 Nov 2016 17:33:47 +0100 Subject: Support LLVM 4.0 in OptimizationDiagnostic FFI - getMsg() changed to return std::string by-value. Fix: copy the data to a rust String during unpacking. - getPassName() changed to return StringRef --- src/rustllvm/RustWrapper.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index b035e134e37..7cde282444d 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -871,16 +871,21 @@ LLVMRustUnpackOptimizationDiagnostic( const char **pass_name_out, LLVMValueRef *function_out, LLVMDebugLocRef *debugloc_out, - LLVMTwineRef *message_out) + RustStringRef message_out) { // Undefined to call this not on an optimization diagnostic! llvm::DiagnosticInfoOptimizationBase *opt = static_cast(unwrap(di)); +#if LLVM_VERSION_GE(4, 0) + *pass_name_out = opt->getPassName().data(); +#else *pass_name_out = opt->getPassName(); +#endif *function_out = wrap(&opt->getFunction()); *debugloc_out = wrap(&opt->getDebugLoc()); - *message_out = wrap(&opt->getMsg()); + raw_rust_string_ostream os(message_out); + os << opt->getMsg(); } extern "C" void -- cgit 1.4.1-3-g733a5 From 2e6d49de07bad57f4619f70326bfa5c2e332fb89 Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Fri, 25 Nov 2016 17:23:25 +0100 Subject: Pass new argument ExportSymbol to DIBuilder::createNameSpace --- src/rustllvm/RustWrapper.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index b035e134e37..62de60d3a26 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -747,7 +747,11 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace( unwrapDI(Scope), Name, unwrapDI(File), - LineNo)); + LineNo +#if LLVM_VERSION_GE(4, 0) + , false // ExportSymbols (only relevant for C++ anonymous namespaces) +#endif + )); } extern "C" void LLVMRustDICompositeTypeSetTypeArray( -- cgit 1.4.1-3-g733a5 From 85dc08e525622365909cdaae27f4b89179321a92 Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Mon, 28 Nov 2016 15:15:51 +0100 Subject: Don't assume llvm::StringRef is null terminated StringRefs have a length and their contents are not usually null-terminated. The solution is to either copy the string data (in rustc_llvm::diagnostic) or take the size into account (in LLVMRustPrintPasses). I couldn't trigger a bug caused by this (apparently all the strings returned in practice are actually null-terminated) but this is more correct and more future-proof. --- src/librustc_llvm/diagnostic.rs | 22 ++++++++++++---------- src/librustc_llvm/ffi.rs | 2 +- src/librustc_trans/back/write.rs | 9 +++------ src/rustllvm/PassWrapper.cpp | 8 +++++--- src/rustllvm/RustWrapper.cpp | 13 +++++-------- 5 files changed, 26 insertions(+), 28 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs index e11274f2064..cef6199a74a 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_llvm/diagnostic.rs @@ -13,7 +13,7 @@ pub use self::OptimizationDiagnosticKind::*; pub use self::Diagnostic::*; -use libc::{c_char, c_uint}; +use libc::c_uint; use std::ptr; use {DiagnosticInfoRef, TwineRef, ValueRef}; @@ -45,7 +45,7 @@ impl OptimizationDiagnosticKind { pub struct OptimizationDiagnostic { pub kind: OptimizationDiagnosticKind, - pub pass_name: *const c_char, + pub pass_name: String, pub function: ValueRef, pub debug_loc: DebugLocRef, pub message: String, @@ -55,21 +55,23 @@ impl OptimizationDiagnostic { unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef) -> OptimizationDiagnostic { - let mut pass_name = ptr::null(); let mut function = ptr::null_mut(); let mut debug_loc = ptr::null_mut(); - let message = super::build_string(|message| - super::LLVMRustUnpackOptimizationDiagnostic(di, - &mut pass_name, - &mut function, - &mut debug_loc, - message) + let mut message = None; + let pass_name = super::build_string(|pass_name| + message = super::build_string(|message| + super::LLVMRustUnpackOptimizationDiagnostic(di, + pass_name, + &mut function, + &mut debug_loc, + message) + ) ); OptimizationDiagnostic { kind: kind, - pass_name: pass_name, + pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"), function: function, debug_loc: debug_loc, message: message.expect("got a non-UTF8 OptimizationDiagnostic message from LLVM") diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 15bca0207c7..98816826b9e 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1820,7 +1820,7 @@ extern "C" { DiagnosticContext: *mut c_void); pub fn LLVMRustUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef, - pass_name_out: *mut *const c_char, + pass_name_out: RustStringRef, function_out: *mut ValueRef, debugloc_out: *mut DebugLocRef, message_out: RustStringRef); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 02993047258..ae5d02c7e04 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -26,7 +26,7 @@ use errors::emitter::Emitter; use syntax_pos::MultiSpan; use context::{is_pie_binary, get_reloc_model}; -use std::ffi::{CStr, CString}; +use std::ffi::CString; use std::fs; use std::path::{Path, PathBuf}; use std::str; @@ -403,19 +403,16 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo } llvm::diagnostic::Optimization(opt) => { - let pass_name = str::from_utf8(CStr::from_ptr(opt.pass_name).to_bytes()) - .ok() - .expect("got a non-UTF8 pass name from LLVM"); let enabled = match cgcx.remark { AllPasses => true, - SomePasses(ref v) => v.iter().any(|s| *s == pass_name), + SomePasses(ref v) => v.iter().any(|s| *s == opt.pass_name), }; if enabled { let loc = llvm::debug_loc_to_string(llcx, opt.debug_loc); cgcx.handler.note_without_error(&format!("optimization {} for {} at {}: {}", opt.kind.describe(), - pass_name, + opt.pass_name, if loc.is_empty() { "[unknown]" } else { &*loc }, opt.message)); } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 9230c639833..d1eb261abd3 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -530,9 +530,11 @@ LLVMRustPrintPasses() { struct MyListener : PassRegistrationListener { void passEnumerate(const PassInfo *info) { #if LLVM_VERSION_GE(4, 0) - if (!info->getPassArgument().empty()) { - printf("%15s - %s\n", info->getPassArgument().data(), - info->getPassName().data()); + StringRef PassArg = info->getPassArgument(); + StringRef PassName = info->getPassName(); + if (!PassArg.empty()) { + printf("%15.*s - %.*s\n", PassArg.size(), PassArg.data(), + PassName.size(), PassName.data()); } #else if (info->getPassArgument() && *info->getPassArgument()) { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 9f0e38b53ff..818737dfe7c 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -872,7 +872,7 @@ LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) { extern "C" void LLVMRustUnpackOptimizationDiagnostic( LLVMDiagnosticInfoRef di, - const char **pass_name_out, + RustStringRef pass_name_out, LLVMValueRef *function_out, LLVMDebugLocRef *debugloc_out, RustStringRef message_out) @@ -881,15 +881,12 @@ LLVMRustUnpackOptimizationDiagnostic( llvm::DiagnosticInfoOptimizationBase *opt = static_cast(unwrap(di)); -#if LLVM_VERSION_GE(4, 0) - *pass_name_out = opt->getPassName().data(); -#else - *pass_name_out = opt->getPassName(); -#endif + raw_rust_string_ostream pass_name_os(pass_name_out); + pass_name_os << opt->getPassName(); *function_out = wrap(&opt->getFunction()); *debugloc_out = wrap(&opt->getDebugLoc()); - raw_rust_string_ostream os(message_out); - os << opt->getMsg(); + raw_rust_string_ostream message_os(message_out); + message_os << opt->getMsg(); } extern "C" void -- cgit 1.4.1-3-g733a5 From dbdd60e6d7b3a812c9461f854f3cd3368ec85942 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Fri, 18 Nov 2016 17:15:14 -0500 Subject: [LLVM] Introduce a stable representation of DIFlags In LLVM 4.0, this enum becomes an actual type-safe enum, which breaks all of the interfaces. Introduce our own copy of the bitflags that we can then safely convert to the LLVM one. --- src/Cargo.lock | 1 + src/librustc_llvm/Cargo.lock | 22 +++++++ src/librustc_llvm/Cargo.toml | 3 + src/librustc_llvm/ffi.rs | 54 ++++++++-------- src/librustc_llvm/lib.rs | 4 ++ src/librustc_trans/debuginfo/metadata.rs | 35 +++++----- src/librustc_trans/debuginfo/mod.rs | 7 +- src/rustllvm/RustWrapper.cpp | 106 +++++++++++++++++++++++++++---- 8 files changed, 172 insertions(+), 60 deletions(-) create mode 100644 src/librustc_llvm/Cargo.lock (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/Cargo.lock b/src/Cargo.lock index bff6ef20677..b3388563adc 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -403,6 +403,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_bitflags 0.0.0", ] [[package]] diff --git a/src/librustc_llvm/Cargo.lock b/src/librustc_llvm/Cargo.lock new file mode 100644 index 00000000000..17678ef2bbd --- /dev/null +++ b/src/librustc_llvm/Cargo.lock @@ -0,0 +1,22 @@ +[root] +name = "rustc_llvm" +version = "0.0.0" +dependencies = [ + "build_helper 0.1.0", + "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_bitflags 0.0.0", +] + +[[package]] +name = "build_helper" +version = "0.1.0" + +[[package]] +name = "gcc" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_bitflags" +version = "0.0.0" + diff --git a/src/librustc_llvm/Cargo.toml b/src/librustc_llvm/Cargo.toml index 88f8c0553ad..f97daa22ff6 100644 --- a/src/librustc_llvm/Cargo.toml +++ b/src/librustc_llvm/Cargo.toml @@ -12,6 +12,9 @@ crate-type = ["dylib"] [features] static-libstdcpp = [] +[dependencies] +rustc_bitflags = { path = "../librustc_bitflags" } + [build-dependencies] build_helper = { path = "../build_helper" } gcc = "0.3.27" diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 98816826b9e..aa64693f6d7 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -11,7 +11,7 @@ use debuginfo::{DIBuilderRef, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType, DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable, DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator, - DINameSpace}; + DINameSpace, DIFlags}; use libc::{c_uint, c_int, size_t, c_char}; use libc::{c_longlong, c_ulonglong, c_void}; @@ -408,7 +408,6 @@ pub enum Visibility { } pub mod debuginfo { - pub use self::DIDescriptorFlags::*; use super::MetadataRef; #[allow(missing_copy_implementations)] @@ -433,24 +432,29 @@ pub mod debuginfo { pub type DIEnumerator = DIDescriptor; pub type DITemplateTypeParameter = DIDescriptor; - #[derive(Copy, Clone)] - pub enum DIDescriptorFlags { - FlagPrivate = 1 << 0, - FlagProtected = 1 << 1, - FlagFwdDecl = 1 << 2, - FlagAppleBlock = 1 << 3, - FlagBlockByrefStruct = 1 << 4, - FlagVirtual = 1 << 5, - FlagArtificial = 1 << 6, - FlagExplicit = 1 << 7, - FlagPrototyped = 1 << 8, - FlagObjcClassComplete = 1 << 9, - FlagObjectPointer = 1 << 10, - FlagVector = 1 << 11, - FlagStaticMember = 1 << 12, - FlagIndirectVariable = 1 << 13, - FlagLValueReference = 1 << 14, - FlagRValueReference = 1 << 15, + // These values **must** match with LLVMRustDIFlags!! + bitflags! { + #[repr(C)] + #[derive(Debug, Default)] + flags DIFlags: ::libc::uint32_t { + const FlagZero = 0, + const FlagPrivate = 1, + const FlagProtected = 2, + const FlagPublic = 3, + const FlagFwdDecl = (1 << 2), + const FlagAppleBlock = (1 << 3), + const FlagBlockByrefStruct = (1 << 4), + const FlagVirtual = (1 << 5), + const FlagArtificial = (1 << 6), + const FlagExplicit = (1 << 7), + const FlagPrototyped = (1 << 8), + const FlagObjcClassComplete = (1 << 9), + const FlagObjectPointer = (1 << 10), + const FlagVector = (1 << 11), + const FlagStaticMember = (1 << 12), + const FlagLValueReference = (1 << 13), + const FlagRValueReference = (1 << 14), + } } } @@ -1567,7 +1571,7 @@ extern "C" { isLocalToUnit: bool, isDefinition: bool, ScopeLine: c_uint, - Flags: c_uint, + Flags: DIFlags, isOptimized: bool, Fn: ValueRef, TParam: DIArray, @@ -1595,7 +1599,7 @@ extern "C" { LineNumber: c_uint, SizeInBits: u64, AlignInBits: u64, - Flags: c_uint, + Flags: DIFlags, DerivedFrom: DIType, Elements: DIArray, RunTimeLang: c_uint, @@ -1611,7 +1615,7 @@ extern "C" { SizeInBits: u64, AlignInBits: u64, OffsetInBits: u64, - Flags: c_uint, + Flags: DIFlags, Ty: DIType) -> DIDerivedType; @@ -1647,7 +1651,7 @@ extern "C" { LineNo: c_uint, Ty: DIType, AlwaysPreserve: bool, - Flags: c_uint, + Flags: DIFlags, ArgNo: c_uint) -> DIVariable; @@ -1707,7 +1711,7 @@ extern "C" { LineNumber: c_uint, SizeInBits: u64, AlignInBits: u64, - Flags: c_uint, + Flags: DIFlags, Elements: DIArray, RunTimeLang: c_uint, UniqueId: *const c_char) diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 0229776c948..f2d978d2d25 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -29,8 +29,12 @@ #![feature(link_args)] #![feature(linked_from)] #![feature(staged_api)] +#![cfg_attr(not(stage0), feature(rustc_private))] extern crate libc; +#[macro_use] +#[no_link] +extern crate rustc_bitflags; pub use self::IntPredicate::*; pub use self::RealPredicate::*; diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index df0e1f1fc05..ca76211dc4c 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -22,7 +22,8 @@ use context::SharedCrateContext; use session::Session; use llvm::{self, ValueRef}; -use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock}; +use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, + DICompositeType, DILexicalBlock, DIFlags}; use rustc::hir::def::CtorKind; use rustc::hir::def_id::DefId; @@ -69,8 +70,6 @@ pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0; // ptr::null() doesn't work :( pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope); -const FLAGS_NONE: c_uint = 0; - #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)] pub struct UniqueTypeId(ast::Name); @@ -347,14 +346,14 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, llvm_type: member_llvm_types[0], type_metadata: element_type_metadata, offset: ComputedMemberOffset, - flags: FLAGS_NONE + flags: DIFlags::FlagZero, }, MemberDescription { name: "length".to_string(), llvm_type: member_llvm_types[1], type_metadata: type_metadata(cx, cx.tcx().types.usize, span), offset: ComputedMemberOffset, - flags: FLAGS_NONE + flags: DIFlags::FlagZero, }, ]; @@ -838,7 +837,7 @@ struct MemberDescription { llvm_type: Type, type_metadata: DIType, offset: MemberOffset, - flags: c_uint + flags: DIFlags, } // A factory for MemberDescriptions. It produces a list of member descriptions @@ -922,7 +921,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> { llvm_type: type_of::type_of(cx, fty), type_metadata: type_metadata(cx, fty, self.span), offset: offset, - flags: FLAGS_NONE, + flags: DIFlags::FlagZero, } }).collect() } @@ -987,7 +986,7 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> { llvm_type: type_of::type_of(cx, component_type), type_metadata: type_metadata(cx, component_type, self.span), offset: ComputedMemberOffset, - flags: FLAGS_NONE, + flags: DIFlags::FlagZero, } }).collect() } @@ -1039,7 +1038,7 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> { llvm_type: type_of::type_of(cx, fty), type_metadata: type_metadata(cx, fty, self.span), offset: FixedMemberOffset { bytes: 0 }, - flags: FLAGS_NONE, + flags: DIFlags::FlagZero, } }).collect() } @@ -1137,7 +1136,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { llvm_type: variant_llvm_type, type_metadata: variant_type_metadata, offset: FixedMemberOffset { bytes: 0 }, - flags: FLAGS_NONE + flags: DIFlags::FlagZero } }).collect() }, @@ -1171,7 +1170,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { llvm_type: variant_llvm_type, type_metadata: variant_type_metadata, offset: FixedMemberOffset { bytes: 0 }, - flags: FLAGS_NONE + flags: DIFlags::FlagZero } ] } @@ -1208,7 +1207,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { llvm_type: non_null_llvm_type, type_metadata: non_null_type_metadata, offset: FixedMemberOffset { bytes: 0 }, - flags: FLAGS_NONE + flags: DIFlags::FlagZero }; let unique_type_id = debug_context(cx).type_map @@ -1245,7 +1244,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { llvm_type: artificial_struct_llvm_type, type_metadata: artificial_struct_metadata, offset: FixedMemberOffset { bytes: 0 }, - flags: FLAGS_NONE + flags: DIFlags::FlagZero } ] }, @@ -1289,7 +1288,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { llvm_type: variant_llvm_type, type_metadata: variant_type_metadata, offset: FixedMemberOffset { bytes: 0 }, - flags: FLAGS_NONE + flags: DIFlags::FlagZero } ] }, @@ -1318,7 +1317,7 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> { _ => type_metadata(cx, ty, self.span) }, offset: ComputedMemberOffset, - flags: FLAGS_NONE + flags: DIFlags::FlagZero } }).collect() } @@ -1535,7 +1534,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, UNKNOWN_LINE_NUMBER, bytes_to_bits(enum_type_size), bytes_to_bits(enum_type_align), - 0, // Flags + DIFlags::FlagZero, ptr::null_mut(), 0, // RuntimeLang unique_type_id_str.as_ptr()) @@ -1680,7 +1679,7 @@ fn create_struct_stub(cx: &CrateContext, UNKNOWN_LINE_NUMBER, bytes_to_bits(struct_size), bytes_to_bits(struct_align), - 0, + DIFlags::FlagZero, ptr::null_mut(), empty_array, 0, @@ -1717,7 +1716,7 @@ fn create_union_stub(cx: &CrateContext, UNKNOWN_LINE_NUMBER, bytes_to_bits(union_size), bytes_to_bits(union_align), - 0, // Flags + DIFlags::FlagZero, empty_array, 0, // RuntimeLang unique_type_id.as_ptr()) diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 482275d298b..e023e654d51 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -22,8 +22,7 @@ use self::source_loc::InternalDebugLocation::{self, UnknownLocation}; use llvm; use llvm::{ModuleRef, ContextRef, ValueRef}; -use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, - FlagPrototyped}; +use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIFlags}; use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; @@ -286,7 +285,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, is_local_to_unit, true, scope_line as c_uint, - FlagPrototyped as c_uint, + DIFlags::FlagPrototyped, cx.sess().opts.optimize != config::OptLevel::No, llfn, template_parameters, @@ -478,7 +477,7 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, loc.line as c_uint, type_metadata, cx.sess().opts.optimize != config::OptLevel::No, - 0, + DIFlags::FlagZero, argument_index) }; source_loc::set_debug_location(cx, None, diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 818737dfe7c..07a7cbdd3d4 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -352,6 +352,86 @@ DIT* unwrapDIptr(LLVMRustMetadataRef ref) { #define DIArray DINodeArray #define unwrapDI unwrapDIptr +// These values **must** match debuginfo::DIFlags! They also *happen* +// to match LLVM, but that isn't required as we do giant sets of +// matching below. The value shouldn't be directly passed to LLVM. +enum class LLVMRustDIFlags : uint32_t { + FlagZero = 0, + FlagPrivate = 1, + FlagProtected = 2, + FlagPublic = 3, + FlagFwdDecl = (1 << 2), + FlagAppleBlock = (1 << 3), + FlagBlockByrefStruct = (1 << 4), + FlagVirtual = (1 << 5), + FlagArtificial = (1 << 6), + FlagExplicit = (1 << 7), + FlagPrototyped = (1 << 8), + FlagObjcClassComplete = (1 << 9), + FlagObjectPointer = (1 << 10), + FlagVector = (1 << 11), + FlagStaticMember = (1 << 12), + FlagLValueReference = (1 << 13), + FlagRValueReference = (1 << 14), + // Do not add values that are not supported by the minimum LLVM + // version we support! +}; + +inline LLVMRustDIFlags operator& (LLVMRustDIFlags a, LLVMRustDIFlags b) { + return static_cast(static_cast(a) & static_cast(b)); +} + +inline LLVMRustDIFlags operator| (LLVMRustDIFlags a, LLVMRustDIFlags b) { + return static_cast(static_cast(a) | static_cast(b)); +} + +inline LLVMRustDIFlags& operator|= (LLVMRustDIFlags& a, LLVMRustDIFlags b) { + return a = a | b; +} + +inline bool is_set(LLVMRustDIFlags f) { + return f != LLVMRustDIFlags::FlagZero; +} + +inline LLVMRustDIFlags visibility(LLVMRustDIFlags f) { + return static_cast(static_cast(f) & 0x3); +} + +static unsigned from_rust(LLVMRustDIFlags flags) { + unsigned result = 0; + + switch (visibility(flags)) { + case LLVMRustDIFlags::FlagPrivate: + result |= DINode::DIFlags::FlagPrivate; + break; + case LLVMRustDIFlags::FlagProtected: + result |= DINode::DIFlags::FlagProtected; + break; + case LLVMRustDIFlags::FlagPublic: + result |= DINode::DIFlags::FlagPublic; + break; + default: + // The rest are handled below + break; + } + + if (is_set(flags & LLVMRustDIFlags::FlagFwdDecl)) { result |= DINode::DIFlags::FlagFwdDecl; } + if (is_set(flags & LLVMRustDIFlags::FlagAppleBlock)) { result |= DINode::DIFlags::FlagAppleBlock; } + if (is_set(flags & LLVMRustDIFlags::FlagBlockByrefStruct)) { result |= DINode::DIFlags::FlagBlockByrefStruct; } + if (is_set(flags & LLVMRustDIFlags::FlagVirtual)) { result |= DINode::DIFlags::FlagVirtual; } + if (is_set(flags & LLVMRustDIFlags::FlagArtificial)) { result |= DINode::DIFlags::FlagArtificial; } + if (is_set(flags & LLVMRustDIFlags::FlagExplicit)) { result |= DINode::DIFlags::FlagExplicit; } + if (is_set(flags & LLVMRustDIFlags::FlagPrototyped)) { result |= DINode::DIFlags::FlagPrototyped; } + if (is_set(flags & LLVMRustDIFlags::FlagObjcClassComplete)) { result |= DINode::DIFlags::FlagObjcClassComplete; } + if (is_set(flags & LLVMRustDIFlags::FlagObjectPointer)) { result |= DINode::DIFlags::FlagObjectPointer; } + if (is_set(flags & LLVMRustDIFlags::FlagVector)) { result |= DINode::DIFlags::FlagVector; } + if (is_set(flags & LLVMRustDIFlags::FlagStaticMember)) { result |= DINode::DIFlags::FlagStaticMember; } + if (is_set(flags & LLVMRustDIFlags::FlagLValueReference)) { result |= DINode::DIFlags::FlagLValueReference; } + if (is_set(flags & LLVMRustDIFlags::FlagRValueReference)) { result |= DINode::DIFlags::FlagRValueReference; } + + return result; +} + extern "C" uint32_t LLVMRustDebugMetadataVersion() { return DEBUG_METADATA_VERSION; } @@ -431,7 +511,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction( bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, - unsigned Flags, + LLVMRustDIFlags Flags, bool isOptimized, LLVMValueRef Fn, LLVMRustMetadataRef TParam, @@ -443,7 +523,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction( unwrapDI(Scope), Name, LinkageName, unwrapDI(File), LineNo, unwrapDI(Ty), isLocalToUnit, isDefinition, ScopeLine, - Flags, isOptimized, + from_rust(Flags), isOptimized, TParams, unwrapDIptr(Decl)); unwrap(Fn)->setSubprogram(Sub); @@ -453,7 +533,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction( unwrapDI(Scope), Name, LinkageName, unwrapDI(File), LineNo, unwrapDI(Ty), isLocalToUnit, isDefinition, ScopeLine, - Flags, isOptimized, + from_rust(Flags), isOptimized, unwrap(Fn), unwrapDIptr(TParam), unwrapDIptr(Decl))); @@ -489,7 +569,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType( unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - unsigned Flags, + LLVMRustDIFlags Flags, LLVMRustMetadataRef DerivedFrom, LLVMRustMetadataRef Elements, unsigned RunTimeLang, @@ -502,7 +582,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType( LineNumber, SizeInBits, AlignInBits, - Flags, + from_rust(Flags), unwrapDI(DerivedFrom), DINodeArray(unwrapDI(Elements)), RunTimeLang, @@ -520,12 +600,12 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType( uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, - unsigned Flags, + LLVMRustDIFlags Flags, LLVMRustMetadataRef Ty) { return wrap(Builder->createMemberType( unwrapDI(Scope), Name, unwrapDI(File), LineNo, - SizeInBits, AlignInBits, OffsetInBits, Flags, + SizeInBits, AlignInBits, OffsetInBits, from_rust(Flags), unwrapDI(Ty))); } @@ -581,7 +661,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable( unsigned LineNo, LLVMRustMetadataRef Ty, bool AlwaysPreserve, - unsigned Flags, + LLVMRustDIFlags Flags, unsigned ArgNo) { #if LLVM_VERSION_GE(3, 8) if (Tag == 0x100) { // DW_TAG_auto_variable @@ -589,20 +669,20 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable( unwrapDI(Scope), Name, unwrapDI(File), LineNo, - unwrapDI(Ty), AlwaysPreserve, Flags)); + unwrapDI(Ty), AlwaysPreserve, from_rust(Flags))); } else { return wrap(Builder->createParameterVariable( unwrapDI(Scope), Name, ArgNo, unwrapDI(File), LineNo, - unwrapDI(Ty), AlwaysPreserve, Flags)); + unwrapDI(Ty), AlwaysPreserve, from_rust(Flags))); } #else return wrap(Builder->createLocalVariable(Tag, unwrapDI(Scope), Name, unwrapDI(File), LineNo, - unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo)); + unwrapDI(Ty), AlwaysPreserve, from_rust(Flags), ArgNo)); #endif } @@ -701,7 +781,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType( unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - unsigned Flags, + LLVMRustDIFlags Flags, LLVMRustMetadataRef Elements, unsigned RunTimeLang, const char* UniqueId) @@ -713,7 +793,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType( LineNumber, SizeInBits, AlignInBits, - Flags, + from_rust(Flags), DINodeArray(unwrapDI(Elements)), RunTimeLang, UniqueId -- cgit 1.4.1-3-g733a5 From 757a9cea3f106483901deab928ad4688d098be3c Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Fri, 18 Nov 2016 16:22:39 -0500 Subject: [LLVM 4.0] Support new DIFlags enum --- src/rustllvm/RustWrapper.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 07a7cbdd3d4..51859a928c4 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -397,8 +397,13 @@ inline LLVMRustDIFlags visibility(LLVMRustDIFlags f) { return static_cast(static_cast(f) & 0x3); } +#if LLVM_VERSION_GE(4, 0) +static DINode::DIFlags from_rust(LLVMRustDIFlags flags) { + DINode::DIFlags result = DINode::DIFlags::FlagZero; +#else static unsigned from_rust(LLVMRustDIFlags flags) { unsigned result = 0; +#endif switch (visibility(flags)) { case LLVMRustDIFlags::FlagPrivate: -- cgit 1.4.1-3-g733a5 From d5f6125fb32078d3331f4c2fddfbcfa303e82232 Mon Sep 17 00:00:00 2001 From: Jake Goulding Date: Thu, 17 Nov 2016 09:10:19 -0500 Subject: [LLVM 4.0] New bitcode headers and API --- src/rustllvm/RustWrapper.cpp | 17 ++++++++++++++++- src/rustllvm/rustllvm.h | 8 +++++++- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 51859a928c4..a6334cf479f 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -892,19 +892,34 @@ extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { Module *Dst = unwrap(dst); + std::unique_ptr buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len)); + +#if LLVM_VERSION_GE(4, 0) + Expected> SrcOrError = + llvm::getLazyBitcodeModule(buf->getMemBufferRef(), Dst->getContext()); + if (!SrcOrError) { + LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str()); + return false; + } + + auto Src = std::move(*SrcOrError); +#else ErrorOr> Src = llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext()); if (!Src) { LLVMRustSetLastError(Src.getError().message().c_str()); return false; } +#endif std::string Err; raw_string_ostream Stream(Err); DiagnosticPrinterRawOStream DP(Stream); -#if LLVM_VERSION_GE(3, 8) +#if LLVM_VERSION_GE(4, 0) + if (Linker::linkModules(*Dst, std::move(Src))) { +#elif LLVM_VERSION_GE(3, 8) if (Linker::linkModules(*Dst, std::move(Src.get()))) { #else if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) { diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 346153d578c..b8c4076f4ce 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -39,7 +39,6 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Vectorize.h" -#include "llvm/Bitcode/ReaderWriter.h" #include "llvm-c/Core.h" #include "llvm-c/BitReader.h" #include "llvm-c/ExecutionEngine.h" @@ -60,6 +59,13 @@ #include "llvm/PassManager.h" #endif +#if LLVM_VERSION_GE(4, 0) +#include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/Bitcode/BitcodeWriter.h" +#else +#include "llvm/Bitcode/ReaderWriter.h" +#endif + #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DIBuilder.h" -- cgit 1.4.1-3-g733a5 From d1a6d47f943d8df9d565de835babc1e2f3e8d45a Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 28 Nov 2016 17:44:51 -0500 Subject: Make LLVM symbol visibility FFI types more stable. --- src/librustc_llvm/ffi.rs | 19 +++++++++++-------- src/librustc_trans/declare.rs | 2 +- src/rustllvm/RustWrapper.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src/rustllvm/RustWrapper.cpp') diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index b8f1540ad84..d2592a3acee 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -64,6 +64,15 @@ pub enum Linkage { CommonLinkage = 10, } +// LLVMRustVisibility +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[repr(C)] +pub enum Visibility { + Default = 0, + Hidden = 1, + Protected = 2, +} + /// LLVMDiagnosticSeverity #[derive(Copy, Clone, Debug)] #[repr(C)] @@ -399,13 +408,6 @@ pub type OperandBundleDefRef = *mut OperandBundleDef_opaque; pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint); -/// LLVMVisibility -#[repr(C)] -pub enum Visibility { - Default, - Hidden, - Protected, -} pub mod debuginfo { use super::MetadataRef; @@ -655,7 +657,8 @@ extern "C" { pub fn LLVMRustSetLinkage(Global: ValueRef, RustLinkage: Linkage); pub fn LLVMGetSection(Global: ValueRef) -> *const c_char; pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char); - pub fn LLVMSetVisibility(Global: ValueRef, Viz: Visibility); + pub fn LLVMRustGetVisibility(Global: ValueRef) -> Visibility; + pub fn LLVMRustSetVisibility(Global: ValueRef, Viz: Visibility); pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint; pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint); pub fn LLVMSetDLLStorageClass(V: ValueRef, C: DLLStorageClass); diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index 7d6a672077a..eef3b9b1147 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -78,7 +78,7 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: // don't want the symbols to get exported. if attr::contains_name(ccx.tcx().map.krate_attrs(), "compiler_builtins") { unsafe { - llvm::LLVMSetVisibility(llfn, llvm::Visibility::Hidden); + llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 51859a928c4..6a95b65d5e9 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1408,3 +1408,45 @@ extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMRustLinkage RustLinkage) extern "C" LLVMContextRef LLVMRustGetValueContext(LLVMValueRef V) { return wrap(&unwrap(V)->getContext()); } + +enum class LLVMRustVisibility { + Default = 0, + Hidden = 1, + Protected = 2, +}; + +static LLVMRustVisibility to_rust(LLVMVisibility vis) { + switch (vis) { + case LLVMDefaultVisibility: + return LLVMRustVisibility::Default; + case LLVMHiddenVisibility: + return LLVMRustVisibility::Hidden; + case LLVMProtectedVisibility: + return LLVMRustVisibility::Protected; + + default: + llvm_unreachable("Invalid LLVMRustVisibility value!"); + } +} + +static LLVMVisibility from_rust(LLVMRustVisibility vis) { + switch (vis) { + case LLVMRustVisibility::Default: + return LLVMDefaultVisibility; + case LLVMRustVisibility::Hidden: + return LLVMHiddenVisibility; + case LLVMRustVisibility::Protected: + return LLVMProtectedVisibility; + + default: + llvm_unreachable("Invalid LLVMRustVisibility value!"); + } +} + +extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) { + return to_rust(LLVMGetVisibility(V)); +} + +extern "C" void LLVMRustSetVisibility(LLVMValueRef V, LLVMRustVisibility RustVisibility) { + LLVMSetVisibility(V, from_rust(RustVisibility)); +} -- cgit 1.4.1-3-g733a5