Auto merge of #21518 - Zoxc:asm-err, r=luqmana
Before: ``` error: invalid operand for inline asm constraint 'i' at line 11 ``` Note that 11 is not the line the inline assembly appears in. After: ``` src/arch/x64/multiboot/bootstrap.rs:203:5: 209:9 error: invalid operand for inline asm constraint 'i' src/arch/x64/multiboot/bootstrap.rs:203 asm! { src/arch/x64/multiboot/bootstrap.rs:204 [multiboot => %ecx, mod attsyntax] src/arch/x64/multiboot/bootstrap.rs:205 src/arch/x64/multiboot/bootstrap.rs:206 ljmp {size_of::<Descriptor>() => %i}, $bootstrap.64 src/arch/x64/multiboot/bootstrap.rs:207 } src/arch/x64/multiboot/bootstrap.rs:208 ... error: aborting due to previous error ```
This commit is contained in:
commit
d15192317a
@ -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)),
|
||||
|
||||
|
@ -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;
|
||||
|
@ -336,30 +336,36 @@ struct HandlerFreeVars<'a> {
|
||||
cgcx: &'a CodegenContext<'a>,
|
||||
}
|
||||
|
||||
unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>,
|
||||
msg: &'b str,
|
||||
cookie: c_uint) {
|
||||
use syntax::codemap::ExpnId;
|
||||
|
||||
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),
|
||||
});
|
||||
}
|
||||
|
||||
None => {
|
||||
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) {
|
||||
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[]),
|
||||
});
|
||||
}
|
||||
|
||||
None => {
|
||||
cgcx.handler.err(&msg[]);
|
||||
cgcx.handler.note("build without -C codegen-units for more exact errors");
|
||||
}
|
||||
}
|
||||
report_inline_asm(cgcx, &msg[], cookie);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) {
|
||||
@ -367,6 +373,12 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
|
||||
= *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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user