@@ -16,6 +16,7 @@ use driver::session::Session;
1616use driver:: config;
1717use llvm;
1818use llvm:: { ModuleRef , TargetMachineRef , PassManagerRef , DiagnosticInfoRef , ContextRef } ;
19+ use llvm:: SMDiagnosticRef ;
1920use util:: common:: time;
2021use syntax:: abi;
2122use syntax:: codemap;
@@ -326,14 +327,40 @@ impl<'a> CodegenContext<'a> {
326327 }
327328}
328329
329- struct DiagHandlerFreeVars < ' a > {
330+ struct HandlerFreeVars < ' a > {
330331 llcx : ContextRef ,
331332 cgcx : & ' a CodegenContext < ' a > ,
332333}
333334
335+ unsafe extern "C" fn inline_asm_handler ( diag : SMDiagnosticRef ,
336+ user : * const c_void ,
337+ cookie : c_uint ) {
338+ use syntax:: codemap:: ExpnId ;
339+
340+ let HandlerFreeVars { cgcx, .. }
341+ = * mem:: transmute :: < _ , * const HandlerFreeVars > ( user) ;
342+
343+ let msg = llvm:: build_string ( |s| llvm:: LLVMWriteSMDiagnosticToString ( diag, s) )
344+ . expect ( "non-UTF8 SMDiagnostic" ) ;
345+
346+ match cgcx. lto_ctxt {
347+ Some ( ( sess, _) ) => {
348+ sess. codemap ( ) . with_expn_info ( ExpnId :: from_llvm_cookie ( cookie) , |info| match info {
349+ Some ( ei) => sess. span_err ( ei. call_site , msg. as_slice ( ) ) ,
350+ None => sess. err ( msg. as_slice ( ) ) ,
351+ } ) ;
352+ }
353+
354+ None => {
355+ cgcx. handler . err ( msg. as_slice ( ) ) ;
356+ cgcx. handler . note ( "build without -C codegen-units for more exact errors" ) ;
357+ }
358+ }
359+ }
360+
334361unsafe extern "C" fn diagnostic_handler ( info : DiagnosticInfoRef , user : * mut c_void ) {
335- let DiagHandlerFreeVars { llcx, cgcx }
336- = * mem:: transmute :: < _ , * const DiagHandlerFreeVars > ( user) ;
362+ let HandlerFreeVars { llcx, cgcx }
363+ = * mem:: transmute :: < _ , * const HandlerFreeVars > ( user) ;
337364
338365 match llvm:: diagnostic:: Diagnostic :: unpack ( info) {
339366 llvm:: diagnostic:: Optimization ( opt) => {
@@ -368,14 +395,16 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
368395 let tm = config. tm ;
369396
370397 // llcx doesn't outlive this function, so we can put this on the stack.
371- let fv = DiagHandlerFreeVars {
398+ let fv = HandlerFreeVars {
372399 llcx : llcx,
373400 cgcx : cgcx,
374401 } ;
402+ let fv = & fv as * const HandlerFreeVars as * mut c_void ;
403+
404+ llvm:: LLVMSetInlineAsmDiagnosticHandler ( llcx, inline_asm_handler, fv) ;
405+
375406 if !cgcx. remark . is_empty ( ) {
376- llvm:: LLVMContextSetDiagnosticHandler ( llcx, diagnostic_handler,
377- & fv as * const DiagHandlerFreeVars
378- as * mut c_void ) ;
407+ llvm:: LLVMContextSetDiagnosticHandler ( llcx, diagnostic_handler, fv) ;
379408 }
380409
381410 if config. emit_no_opt_bc {
0 commit comments