about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_llvm/diagnostic.rs33
-rw-r--r--src/librustc_llvm/lib.rs4
-rw-r--r--src/librustc_trans/back/write.rs41
-rw-r--r--src/rustllvm/RustWrapper.cpp16
4 files changed, 77 insertions, 17 deletions
diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs
index db2a569cdef..5d0ae9d1f92 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;
+use libc::{c_char, c_uint};
 use std::ptr;
 
 use {ValueRef, TwineRef, DebugLocRef, DiagnosticInfoRef};
@@ -69,9 +69,37 @@ impl OptimizationDiagnostic {
     }
 }
 
+pub struct InlineAsmDiagnostic {
+    pub cookie: c_uint,
+    pub message: TwineRef,
+    pub instruction: ValueRef,
+}
+
+impl Copy for InlineAsmDiagnostic {}
+
+impl InlineAsmDiagnostic {
+    unsafe fn unpack(di: DiagnosticInfoRef)
+            -> InlineAsmDiagnostic {
+
+        let mut opt = InlineAsmDiagnostic {
+            cookie: 0,
+            message: ptr::null_mut(),
+            instruction: ptr::null_mut(),
+        };
+
+        super::LLVMUnpackInlineAsmDiagnostic(di,
+            &mut opt.cookie,
+            &mut opt.message,
+            &mut opt.instruction);
+
+        opt
+    }
+}
+
 #[derive(Copy)]
 pub enum Diagnostic {
     Optimization(OptimizationDiagnostic),
+    InlineAsm(InlineAsmDiagnostic),
 
     /// LLVM has other types that we do not wrap here.
     UnknownDiagnostic(DiagnosticInfoRef),
@@ -82,6 +110,9 @@ impl Diagnostic {
         let kind = super::LLVMGetDiagInfoKind(di);
 
         match kind {
+            super::DK_InlineAsm
+                => InlineAsm(InlineAsmDiagnostic::unpack(di)),
+
             super::DK_OptimizationRemark
                 => Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di)),
 
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index eded88bb62e..8c651cf839b 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -2049,6 +2049,10 @@ extern {
                                             function_out: *mut ValueRef,
                                             debugloc_out: *mut DebugLocRef,
                                             message_out: *mut TwineRef);
+    pub fn LLVMUnpackInlineAsmDiagnostic(DI: DiagnosticInfoRef,
+                                            cookie_out: *mut c_uint,
+                                            message_out: *mut TwineRef,
+                                            instruction_out: *mut ValueRef);
 
     pub fn LLVMWriteDiagnosticInfoToString(DI: DiagnosticInfoRef, s: RustStringRef);
     pub fn LLVMGetDiagInfoSeverity(DI: DiagnosticInfoRef) -> DiagnosticSeverity;
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index b07c2060e69..5e48ce384be 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -336,37 +336,49 @@ struct HandlerFreeVars<'a> {
     cgcx: &'a CodegenContext<'a>,
 }
 
-unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
-                                        user: *const c_void,
-                                        cookie: c_uint) {
+unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>,
+                                           msg: &'b str,
+                                           cookie: c_uint) {
     use syntax::codemap::ExpnId;
 
-    let HandlerFreeVars { cgcx, .. }
-        = *mem::transmute::<_, *const HandlerFreeVars>(user);
-
-    let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
-        .expect("non-UTF8 SMDiagnostic");
-
     match cgcx.lto_ctxt {
         Some((sess, _)) => {
             sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info {
-                Some(ei) => sess.span_err(ei.call_site, &msg[]),
-                None     => sess.err(&msg[]),
+                Some(ei) => sess.span_err(ei.call_site, msg),
+                None     => sess.err(msg),
             });
         }
 
         None => {
-            cgcx.handler.err(&msg[]);
+            cgcx.handler.err(msg);
             cgcx.handler.note("build without -C codegen-units for more exact errors");
         }
     }
 }
 
+unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef,
+                                        user: *const c_void,
+                                        cookie: c_uint) {
+    let HandlerFreeVars { cgcx, .. }
+        = *mem::transmute::<_, *const HandlerFreeVars>(user);
+
+    let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s))
+        .expect("non-UTF8 SMDiagnostic");
+
+    report_inline_asm(cgcx, &msg[], cookie);
+}
+
 unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
     let HandlerFreeVars { llcx, cgcx }
         = *mem::transmute::<_, *const HandlerFreeVars>(user);
 
     match llvm::diagnostic::Diagnostic::unpack(info) {
+        llvm::diagnostic::InlineAsm(inline) => {
+            report_inline_asm(cgcx,
+                              llvm::twine_to_string(inline.message).as_slice(),
+                              inline.cookie);
+        }
+
         llvm::diagnostic::Optimization(opt) => {
             let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name))
                                 .ok()
@@ -407,10 +419,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);
-
-    if !cgcx.remark.is_empty() {
-        llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
-    }
+    llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv);
 
     if config.emit_no_opt_bc {
         let ext = format!("{}.no-opt.bc", name_extra);
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index bce73a27699..728ff1461fc 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -894,6 +894,22 @@ LLVMUnpackOptimizationDiagnostic(
     *message_out = wrap(&opt->getMsg());
 }
 
+extern "C" void
+LLVMUnpackInlineAsmDiagnostic(
+    LLVMDiagnosticInfoRef di,
+    unsigned *cookie_out,
+    LLVMTwineRef *message_out,
+    LLVMValueRef *instruction_out)
+{
+    // Undefined to call this not on an inline assembly diagnostic!
+    llvm::DiagnosticInfoInlineAsm *ia
+        = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
+
+    *cookie_out = ia->getLocCookie();
+    *message_out = wrap(&ia->getMsgStr());
+    *instruction_out = wrap(ia->getInstruction());
+}
+
 extern "C" void LLVMWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
     raw_rust_string_ostream os(str);
     DiagnosticPrinterRawOStream dp(os);