about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_llvm/diagnostic.rs32
-rw-r--r--src/librustc_llvm/ffi.rs4
-rw-r--r--src/librustc_trans/back/write.rs14
-rw-r--r--src/rustllvm/ArchiveWrapper.cpp4
-rw-r--r--src/rustllvm/RustWrapper.cpp227
-rw-r--r--src/rustllvm/rustllvm.h2
-rw-r--r--src/test/codegen/lifetime_start_end.rs16
7 files changed, 194 insertions, 105 deletions
diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs
index cef6199a74a..c5276e0c971 100644
--- a/src/librustc_llvm/diagnostic.rs
+++ b/src/librustc_llvm/diagnostic.rs
@@ -17,7 +17,6 @@ use libc::c_uint;
 use std::ptr;
 
 use {DiagnosticInfoRef, TwineRef, ValueRef};
-use ffi::DebugLocRef;
 
 #[derive(Copy, Clone)]
 pub enum OptimizationDiagnosticKind {
@@ -47,7 +46,9 @@ pub struct OptimizationDiagnostic {
     pub kind: OptimizationDiagnosticKind,
     pub pass_name: String,
     pub function: ValueRef,
-    pub debug_loc: DebugLocRef,
+    pub line: c_uint,
+    pub column: c_uint,
+    pub filename: String,
     pub message: String,
 }
 
@@ -56,24 +57,37 @@ impl OptimizationDiagnostic {
                      di: DiagnosticInfoRef)
                      -> OptimizationDiagnostic {
         let mut function = ptr::null_mut();
-        let mut debug_loc = ptr::null_mut();
+        let mut line = 0;
+        let mut column = 0;
 
         let mut message = None;
+        let mut filename = 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)
+                filename = super::build_string(|filename|
+                    super::LLVMRustUnpackOptimizationDiagnostic(di,
+                                                                pass_name,
+                                                                &mut function,
+                                                                &mut line,
+                                                                &mut column,
+                                                                filename,
+                                                                message)
+                )
             )
         );
 
+        let mut filename = filename.unwrap_or(String::new());
+        if filename.is_empty() {
+            filename.push_str("<unknown file>");
+        }
+
         OptimizationDiagnostic {
             kind: kind,
             pass_name: pass_name.expect("got a non-UTF8 pass name from LLVM"),
             function: function,
-            debug_loc: debug_loc,
+            line: line,
+            column: column,
+            filename: filename,
             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 9f0ee95b5a6..24d4040ccb0 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -1633,7 +1633,9 @@ extern "C" {
     pub fn LLVMRustUnpackOptimizationDiagnostic(DI: DiagnosticInfoRef,
                                                 pass_name_out: RustStringRef,
                                                 function_out: *mut ValueRef,
-                                                debugloc_out: *mut DebugLocRef,
+                                                loc_line_out: *mut c_uint,
+                                                loc_column_out: *mut c_uint,
+                                                loc_filename_out: RustStringRef,
                                                 message_out: RustStringRef);
     pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
                                              cookie_out: *mut c_uint,
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 5e227ec467a..26553c85023 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -16,7 +16,7 @@ use rustc::session::config::{self, OutputFilenames, OutputType, OutputTypes, Pas
                              AllPasses, Sanitizer};
 use rustc::session::Session;
 use llvm;
-use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
+use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
 use llvm::SMDiagnosticRef;
 use {CrateTranslation, ModuleLlvm, ModuleSource, ModuleTranslation};
 use rustc::hir::def_id::CrateNum;
@@ -307,7 +307,6 @@ pub struct CodegenContext<'a> {
 }
 
 struct HandlerFreeVars<'a> {
-    llcx: ContextRef,
     cgcx: &'a CodegenContext<'a>,
 }
 
@@ -329,7 +328,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
 }
 
 unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
-    let HandlerFreeVars { llcx, cgcx } = *(user as *const HandlerFreeVars);
+    let HandlerFreeVars { cgcx, .. } = *(user as *const HandlerFreeVars);
 
     match llvm::diagnostic::Diagnostic::unpack(info) {
         llvm::diagnostic::InlineAsm(inline) => {
@@ -345,11 +344,12 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
             };
 
             if enabled {
-                let loc = llvm::debug_loc_to_string(llcx, opt.debug_loc);
-                cgcx.handler.note_without_error(&format!("optimization {} for {} at {}: {}",
+                cgcx.handler.note_without_error(&format!("optimization {} for {} at {}:{}:{}: {}",
                                                 opt.kind.describe(),
                                                 opt.pass_name,
-                                                if loc.is_empty() { "[unknown]" } else { &*loc },
+                                                opt.filename,
+                                                opt.line,
+                                                opt.column,
                                                 opt.message));
             }
         }
@@ -370,9 +370,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     let llcx = mllvm.llcx;
     let tm = config.tm;
 
-    // llcx doesn't outlive this function, so we can put this on the stack.
     let fv = HandlerFreeVars {
-        llcx: llcx,
         cgcx: cgcx,
     };
     let fv = &fv as *const HandlerFreeVars as *mut c_void;
diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp
index f04251136f4..7f76861c077 100644
--- a/src/rustllvm/ArchiveWrapper.cpp
+++ b/src/rustllvm/ArchiveWrapper.cpp
@@ -12,6 +12,7 @@
 
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/ArchiveWriter.h"
+#include "llvm/Support/Path.h"
 
 using namespace llvm;
 using namespace llvm::object;
@@ -256,6 +257,9 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers,
         LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
         return LLVMRustResult::Failure;
       }
+#if LLVM_VERSION_GE(5, 0)
+      MOrErr->MemberName = sys::path::filename(MOrErr->MemberName);
+#endif
       Members.push_back(std::move(*MOrErr));
 #elif LLVM_VERSION_EQ(3, 8)
       Members.push_back(NewArchiveIterator(Member->Filename));
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index c11c5f4186e..15a04ba00e2 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -18,6 +18,10 @@
 
 #include "llvm/IR/CallSite.h"
 
+#if LLVM_VERSION_GE(5, 0)
+#include "llvm/ADT/Optional.h"
+#endif
+
 //===----------------------------------------------------------------------===
 //
 // This file defines alternate interfaces to core functions that are more
@@ -163,10 +167,14 @@ extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned Index,
                                              LLVMRustAttribute RustAttr) {
   CallSite Call = CallSite(unwrap<Instruction>(Instr));
   Attribute Attr = Attribute::get(Call->getContext(), fromRust(RustAttr));
+#if LLVM_VERSION_GE(5, 0)
+  Call.addAttribute(Index, Attr);
+#else
   AttrBuilder B(Attr);
   Call.setAttributes(Call.getAttributes().addAttributes(
       Call->getContext(), Index,
       AttributeSet::get(Call->getContext(), Index, B)));
+#endif
 }
 
 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
@@ -175,9 +183,14 @@ extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
   CallSite Call = CallSite(unwrap<Instruction>(Instr));
   AttrBuilder B;
   B.addDereferenceableAttr(Bytes);
+#if LLVM_VERSION_GE(5, 0)
+  Call.setAttributes(Call.getAttributes().addAttributes(
+      Call->getContext(), Index, B));
+#else
   Call.setAttributes(Call.getAttributes().addAttributes(
       Call->getContext(), Index,
       AttributeSet::get(Call->getContext(), Index, B)));
+#endif
 }
 
 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
@@ -185,7 +198,11 @@ extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn, unsigned Index,
   Function *A = unwrap<Function>(Fn);
   Attribute Attr = Attribute::get(A->getContext(), fromRust(RustAttr));
   AttrBuilder B(Attr);
+#if LLVM_VERSION_GE(5, 0)
+  A->addAttributes(Index, B);
+#else
   A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
+#endif
 }
 
 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
@@ -193,7 +210,11 @@ extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn, unsigned Index,
   Function *A = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addDereferenceableAttr(Bytes);
+#if LLVM_VERSION_GE(5, 0)
+  A->addAttributes(Index, B);
+#else
   A->addAttributes(Index, AttributeSet::get(A->getContext(), Index, B));
+#endif
 }
 
 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
@@ -203,18 +224,26 @@ extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
   Function *F = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addAttribute(Name, Value);
+#if LLVM_VERSION_GE(5, 0)
+  F->addAttributes(Index, B);
+#else
   F->addAttributes(Index, AttributeSet::get(F->getContext(), Index, B));
+#endif
 }
 
 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
                                                  unsigned Index,
                                                  LLVMRustAttribute RustAttr) {
   Function *F = unwrap<Function>(Fn);
-  const AttributeSet PAL = F->getAttributes();
   Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
   AttrBuilder B(Attr);
+  auto PAL = F->getAttributes();
+#if LLVM_VERSION_GE(5, 0)
+  auto PALNew = PAL.removeAttributes(F->getContext(), Index, B);
+#else
   const AttributeSet PALNew = PAL.removeAttributes(
       F->getContext(), Index, AttributeSet::get(F->getContext(), Index, B));
+#endif
   F->setAttributes(PALNew);
 }
 
@@ -263,6 +292,18 @@ enum class LLVMRustSynchronizationScope {
   CrossThread,
 };
 
+#if LLVM_VERSION_GE(5, 0)
+static SyncScope::ID fromRust(LLVMRustSynchronizationScope Scope) {
+  switch (Scope) {
+  case LLVMRustSynchronizationScope::SingleThread:
+    return SyncScope::SingleThread;
+  case LLVMRustSynchronizationScope::CrossThread:
+    return SyncScope::System;
+  default:
+    llvm_unreachable("bad SynchronizationScope.");
+  }
+}
+#else
 static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) {
   switch (Scope) {
   case LLVMRustSynchronizationScope::SingleThread:
@@ -273,6 +314,7 @@ static SynchronizationScope fromRust(LLVMRustSynchronizationScope Scope) {
     llvm_unreachable("bad SynchronizationScope.");
   }
 }
+#endif
 
 extern "C" LLVMValueRef
 LLVMRustBuildAtomicFence(LLVMBuilderRef B, LLVMAtomicOrdering Order,
@@ -318,17 +360,19 @@ extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm)
 
 typedef DIBuilder *LLVMRustDIBuilderRef;
 
-typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
+#if LLVM_VERSION_LT(5, 0)
+typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
 
 namespace llvm {
-DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
+DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
 
-inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
+inline Metadata **unwrap(LLVMMetadataRef *Vals) {
   return reinterpret_cast<Metadata **>(Vals);
 }
 }
+#endif
 
-template <typename DIT> DIT *unwrapDIPtr(LLVMRustMetadataRef Ref) {
+template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
   return (DIT *)(Ref ? unwrap<MDNode>(Ref) : nullptr);
 }
 
@@ -466,7 +510,7 @@ extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
   unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
 }
 
-extern "C" void LLVMRustMetadataAsValue(LLVMContextRef C, LLVMRustMetadataRef MD) {
+extern "C" void LLVMRustMetadataAsValue(LLVMContextRef C, LLVMMetadataRef MD) {
   wrap(MetadataAsValue::get(*unwrap(C), unwrap(MD)));
 }
 
@@ -482,8 +526,8 @@ extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
   Builder->finalize();
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
-    LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMRustMetadataRef FileRef,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit(
+    LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef,
     const char *Producer, bool isOptimized, const char *Flags,
     unsigned RuntimeVer, const char *SplitName) {
   auto *File = unwrapDI<DIFile>(FileRef);
@@ -498,16 +542,16 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
 #endif
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename,
                             const char *Directory) {
   return wrap(Builder->createFile(Filename, Directory));
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
-                                      LLVMRustMetadataRef File,
-                                      LLVMRustMetadataRef ParameterTypes) {
+                                      LLVMMetadataRef File,
+                                      LLVMMetadataRef ParameterTypes) {
   return wrap(Builder->createSubroutineType(
 #if LLVM_VERSION_EQ(3, 7)
       unwrapDI<DIFile>(File),
@@ -515,12 +559,12 @@ LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder,
       DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
-    const char *LinkageName, LLVMRustMetadataRef File, unsigned LineNo,
-    LLVMRustMetadataRef Ty, bool IsLocalToUnit, bool IsDefinition,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
+    LLVMMetadataRef Ty, bool IsLocalToUnit, bool IsDefinition,
     unsigned ScopeLine, LLVMRustDIFlags Flags, bool IsOptimized,
-    LLVMValueRef Fn, LLVMRustMetadataRef TParam, LLVMRustMetadataRef Decl) {
+    LLVMValueRef Fn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) {
 #if LLVM_VERSION_GE(3, 8)
   DITemplateParameterArray TParams =
       DITemplateParameterArray(unwrap<MDTuple>(TParam));
@@ -540,7 +584,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
 #endif
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
                                  uint64_t SizeInBits, uint32_t AlignInBits,
                                  unsigned Encoding) {
@@ -551,19 +595,23 @@ LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name,
                                        Encoding));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef PointeeTy,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
     uint64_t SizeInBits, uint32_t AlignInBits, const char *Name) {
   return wrap(Builder->createPointerType(unwrapDI<DIType>(PointeeTy),
-                                         SizeInBits, AlignInBits, Name));
+                                         SizeInBits, AlignInBits,
+#if LLVM_VERSION_GE(5, 0)
+                                         /* DWARFAddressSpace */ None,
+#endif
+                                         Name));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
-    LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
     uint32_t AlignInBits, LLVMRustDIFlags Flags,
-    LLVMRustMetadataRef DerivedFrom, LLVMRustMetadataRef Elements,
-    unsigned RunTimeLang, LLVMRustMetadataRef VTableHolder,
+    LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements,
+    unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
     const char *UniqueId) {
   return wrap(Builder->createStructType(
       unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
@@ -572,37 +620,37 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
       unwrapDI<DIType>(VTableHolder), UniqueId));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
-    LLVMRustMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
     uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags,
-    LLVMRustMetadataRef Ty) {
+    LLVMMetadataRef Ty) {
   return wrap(Builder->createMemberType(unwrapDI<DIDescriptor>(Scope), Name,
                                         unwrapDI<DIFile>(File), LineNo,
                                         SizeInBits, AlignInBits, OffsetInBits,
                                         fromRust(Flags), unwrapDI<DIType>(Ty)));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope,
-    LLVMRustMetadataRef File, unsigned Line, unsigned Col) {
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
+    LLVMMetadataRef File, unsigned Line, unsigned Col) {
   return wrap(Builder->createLexicalBlock(unwrapDI<DIDescriptor>(Scope),
                                           unwrapDI<DIFile>(File), Line, Col));
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateLexicalBlockFile(LLVMRustDIBuilderRef Builder,
-                                        LLVMRustMetadataRef Scope,
-                                        LLVMRustMetadataRef File) {
+                                        LLVMMetadataRef Scope,
+                                        LLVMMetadataRef File) {
   return wrap(Builder->createLexicalBlockFile(unwrapDI<DIDescriptor>(Scope),
                                               unwrapDI<DIFile>(File)));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Context, const char *Name,
-    const char *LinkageName, LLVMRustMetadataRef File, unsigned LineNo,
-    LLVMRustMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
-    LLVMRustMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
+    const char *LinkageName, LLVMMetadataRef File, unsigned LineNo,
+    LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V,
+    LLVMMetadataRef Decl = nullptr, uint32_t AlignInBits = 0) {
   llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
 
 #if LLVM_VERSION_GE(4, 0)
@@ -632,10 +680,10 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
 #endif
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
-    LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMRustMetadataRef Scope,
-    const char *Name, LLVMRustMetadataRef File, unsigned LineNo,
-    LLVMRustMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable(
+    LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope,
+    const char *Name, LLVMMetadataRef File, unsigned LineNo,
+    LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags,
     unsigned ArgNo, uint32_t AlignInBits) {
 #if LLVM_VERSION_GE(3, 8)
   if (Tag == 0x100) { // DW_TAG_auto_variable
@@ -659,40 +707,40 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
 #endif
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size,
-                                 uint32_t AlignInBits, LLVMRustMetadataRef Ty,
-                                 LLVMRustMetadataRef Subscripts) {
+                                 uint32_t AlignInBits, LLVMMetadataRef Ty,
+                                 LLVMMetadataRef Subscripts) {
   return wrap(
       Builder->createArrayType(Size, AlignInBits, unwrapDI<DIType>(Ty),
                                DINodeArray(unwrapDI<MDTuple>(Subscripts))));
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateVectorType(LLVMRustDIBuilderRef Builder, uint64_t Size,
-                                  uint32_t AlignInBits, LLVMRustMetadataRef Ty,
-                                  LLVMRustMetadataRef Subscripts) {
+                                  uint32_t AlignInBits, LLVMMetadataRef Ty,
+                                  LLVMMetadataRef Subscripts) {
   return wrap(
       Builder->createVectorType(Size, AlignInBits, unwrapDI<DIType>(Ty),
                                 DINodeArray(unwrapDI<MDTuple>(Subscripts))));
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo,
                                      int64_t Count) {
   return wrap(Builder->getOrCreateSubrange(Lo, Count));
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder,
-                                  LLVMRustMetadataRef *Ptr, unsigned Count) {
+                                  LLVMMetadataRef *Ptr, unsigned Count) {
   Metadata **DataValue = unwrap(Ptr);
   return wrap(
       Builder->getOrCreateArray(ArrayRef<Metadata *>(DataValue, Count)).get());
 }
 
 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
-    LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMRustMetadataRef VarInfo,
+    LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo,
     int64_t *AddrOps, unsigned AddrOpsCount, LLVMValueRef DL,
     LLVMBasicBlockRef InsertAtEnd) {
   return wrap(Builder->insertDeclare(
@@ -702,27 +750,27 @@ extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
       unwrap(InsertAtEnd)));
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateEnumerator(LLVMRustDIBuilderRef Builder,
                                   const char *Name, uint64_t Val) {
   return wrap(Builder->createEnumerator(Name, Val));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
-    LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
-    uint32_t AlignInBits, LLVMRustMetadataRef Elements,
-    LLVMRustMetadataRef ClassTy) {
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
+    uint32_t AlignInBits, LLVMMetadataRef Elements,
+    LLVMMetadataRef ClassTy) {
   return wrap(Builder->createEnumerationType(
       unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
       SizeInBits, AlignInBits, DINodeArray(unwrapDI<MDTuple>(Elements)),
       unwrapDI<DIType>(ClassTy)));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
-    LLVMRustMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
-    uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMRustMetadataRef Elements,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
+    uint32_t AlignInBits, LLVMRustDIFlags Flags, LLVMMetadataRef Elements,
     unsigned RunTimeLang, const char *UniqueId) {
   return wrap(Builder->createUnionType(
       unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNumber,
@@ -730,20 +778,24 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
       DINodeArray(unwrapDI<MDTuple>(Elements)), RunTimeLang, UniqueId));
 }
 
-extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
-    LLVMRustDIBuilderRef Builder, LLVMRustMetadataRef Scope, const char *Name,
-    LLVMRustMetadataRef Ty, LLVMRustMetadataRef File, unsigned LineNo,
+extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
+    LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
+    LLVMMetadataRef Ty, LLVMMetadataRef File, unsigned LineNo,
     unsigned ColumnNo) {
   return wrap(Builder->createTemplateTypeParameter(
       unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIType>(Ty)));
 }
 
-extern "C" LLVMRustMetadataRef
+extern "C" LLVMMetadataRef
 LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
-                                 LLVMRustMetadataRef Scope, const char *Name,
-                                 LLVMRustMetadataRef File, unsigned LineNo) {
+                                 LLVMMetadataRef Scope, const char *Name,
+                                 LLVMMetadataRef File, unsigned LineNo) {
   return wrap(Builder->createNameSpace(
-      unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), LineNo
+      unwrapDI<DIDescriptor>(Scope), Name
+#if LLVM_VERSION_LT(5, 0)
+      ,
+      unwrapDI<DIFile>(File), LineNo
+#endif
 #if LLVM_VERSION_GE(4, 0)
       ,
       false // ExportSymbols (only relevant for C++ anonymous namespaces)
@@ -753,16 +805,16 @@ LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
 
 extern "C" void
 LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
-                                    LLVMRustMetadataRef CompositeTy,
-                                    LLVMRustMetadataRef TyArray) {
+                                    LLVMMetadataRef CompositeTy,
+                                    LLVMMetadataRef TyArray) {
   DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
   Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
 }
 
 extern "C" LLVMValueRef
 LLVMRustDIBuilderCreateDebugLocation(LLVMContextRef ContextRef, unsigned Line,
-                                     unsigned Column, LLVMRustMetadataRef Scope,
-                                     LLVMRustMetadataRef InlinedAt) {
+                                     unsigned Column, LLVMMetadataRef Scope,
+                                     LLVMMetadataRef InlinedAt) {
   LLVMContext &Context = *unwrap(ContextRef);
 
   DebugLoc debug_loc = DebugLoc::get(Line, Column, unwrapDIPtr<MDNode>(Scope),
@@ -879,8 +931,8 @@ extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
 
 extern "C" void LLVMRustUnpackOptimizationDiagnostic(
     LLVMDiagnosticInfoRef DI, RustStringRef PassNameOut,
-    LLVMValueRef *FunctionOut, LLVMDebugLocRef *DebugLocOut,
-    RustStringRef MessageOut) {
+    LLVMValueRef *FunctionOut, unsigned* Line, unsigned* Column,
+    RustStringRef FilenameOut, RustStringRef MessageOut) {
   // Undefined to call this not on an optimization diagnostic!
   llvm::DiagnosticInfoOptimizationBase *Opt =
       static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
@@ -888,7 +940,24 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic(
   RawRustStringOstream PassNameOS(PassNameOut);
   PassNameOS << Opt->getPassName();
   *FunctionOut = wrap(&Opt->getFunction());
-  *DebugLocOut = wrap(&Opt->getDebugLoc());
+
+  RawRustStringOstream FilenameOS(FilenameOut);
+#if LLVM_VERSION_GE(5,0)
+  DiagnosticLocation loc = Opt->getLocation();
+  if (loc.isValid()) {
+    *Line = loc.getLine();
+    *Column = loc.getColumn();
+    FilenameOS << loc.getFilename();
+  }
+#else
+  const DebugLoc &loc = Opt->getDebugLoc();
+  if (loc) {
+    *Line = loc.getLine();
+    *Column = loc.getCol();
+    FilenameOS << cast<DIScope>(loc.getScope())->getFilename();
+  }
+#endif
+
   RawRustStringOstream MessageOS(MessageOut);
   MessageOS << Opt->getMsg();
 }
diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h
index 0baf5528e93..20816af2f1c 100644
--- a/src/rustllvm/rustllvm.h
+++ b/src/rustllvm/rustllvm.h
@@ -55,6 +55,8 @@
   (LLVM_VERSION_MAJOR < (major) ||                                             \
    LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR <= (minor))
 
+#define LLVM_VERSION_LT(major, minor) (!LLVM_VERSION_GE((major), (minor)))
+
 #if LLVM_VERSION_GE(3, 7)
 #include "llvm/IR/LegacyPassManager.h"
 #else
diff --git a/src/test/codegen/lifetime_start_end.rs b/src/test/codegen/lifetime_start_end.rs
index 5c1f1f8f2bb..1f900a3770e 100644
--- a/src/test/codegen/lifetime_start_end.rs
+++ b/src/test/codegen/lifetime_start_end.rs
@@ -19,34 +19,34 @@ pub fn test() {
     &a; // keep variable in an alloca
 
 // CHECK: [[S_a:%[0-9]+]] = bitcast i32* %a to i8*
-// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_a]])
+// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, i8* [[S_a]])
 
     {
         let b = &Some(a);
         &b; // keep variable in an alloca
 
 // CHECK: [[S_b:%[0-9]+]] = bitcast %"core::option::Option<i32>"** %b to i8*
-// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_b]])
+// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, i8* [[S_b]])
 
 // CHECK: [[S__5:%[0-9]+]] = bitcast %"core::option::Option<i32>"* %_5 to i8*
-// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S__5]])
+// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, i8* [[S__5]])
 
 // CHECK: [[E_b:%[0-9]+]] = bitcast %"core::option::Option<i32>"** %b to i8*
-// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_b]])
+// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, i8* [[E_b]])
 
 // CHECK: [[E__5:%[0-9]+]] = bitcast %"core::option::Option<i32>"* %_5 to i8*
-// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E__5]])
+// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, i8* [[E__5]])
     }
 
     let c = 1;
     &c; // keep variable in an alloca
 
 // CHECK: [[S_c:%[0-9]+]] = bitcast i32* %c to i8*
-// CHECK: call void @llvm.lifetime.start(i{{[0-9 ]+}}, i8* [[S_c]])
+// CHECK: call void @llvm.lifetime.start{{.*}}(i{{[0-9 ]+}}, i8* [[S_c]])
 
 // CHECK: [[E_c:%[0-9]+]] = bitcast i32* %c to i8*
-// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_c]])
+// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, i8* [[E_c]])
 
 // CHECK: [[E_a:%[0-9]+]] = bitcast i32* %a to i8*
-// CHECK: call void @llvm.lifetime.end(i{{[0-9 ]+}}, i8* [[E_a]])
+// CHECK: call void @llvm.lifetime.end{{.*}}(i{{[0-9 ]+}}, i8* [[E_a]])
 }