Pass end position of span through inline ASM cookie
This commit is contained in:
parent
f2abf827c1
commit
68227a3777
24 changed files with 1565 additions and 200 deletions
|
@ -504,14 +504,13 @@ pub(crate) fn inline_asm_call<'ll>(
|
|||
let key = "srcloc";
|
||||
let kind = llvm::LLVMGetMDKindIDInContext(
|
||||
bx.llcx,
|
||||
key.as_ptr() as *const c_char,
|
||||
key.as_ptr().cast::<c_char>(),
|
||||
key.len() as c_uint,
|
||||
);
|
||||
|
||||
// srcloc contains one integer for each line of assembly code.
|
||||
// Unfortunately this isn't enough to encode a full span so instead
|
||||
// we just encode the start position of each line.
|
||||
// FIXME: Figure out a way to pass the entire line spans.
|
||||
// `srcloc` contains one 64-bit integer for each line of assembly code,
|
||||
// where the lower 32 bits hold the lo byte position and the upper 32 bits
|
||||
// hold the hi byte position.
|
||||
let mut srcloc = vec![];
|
||||
if dia == llvm::AsmDialect::Intel && line_spans.len() > 1 {
|
||||
// LLVM inserts an extra line to add the ".intel_syntax", so add
|
||||
|
@ -521,13 +520,13 @@ pub(crate) fn inline_asm_call<'ll>(
|
|||
// due to the asm template string coming from a macro. LLVM will
|
||||
// default to the first srcloc for lines that don't have an
|
||||
// associated srcloc.
|
||||
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_i32(0)));
|
||||
srcloc.push(llvm::LLVMValueAsMetadata(bx.const_u64(0)));
|
||||
}
|
||||
srcloc.extend(
|
||||
line_spans
|
||||
.iter()
|
||||
.map(|span| llvm::LLVMValueAsMetadata(bx.const_i32(span.lo().to_u32() as i32))),
|
||||
);
|
||||
srcloc.extend(line_spans.iter().map(|span| {
|
||||
llvm::LLVMValueAsMetadata(bx.const_u64(
|
||||
u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32),
|
||||
))
|
||||
}));
|
||||
let md = llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len());
|
||||
let md = llvm::LLVMMetadataAsValue(&bx.llcx, md);
|
||||
llvm::LLVMSetMetadata(call, kind, md);
|
||||
|
|
|
@ -25,8 +25,8 @@ use rustc_session::Session;
|
|||
use rustc_session::config::{
|
||||
self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath,
|
||||
};
|
||||
use rustc_span::InnerSpan;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext};
|
||||
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
|
||||
use tracing::debug;
|
||||
|
||||
|
@ -413,21 +413,32 @@ fn report_inline_asm(
|
|||
cgcx: &CodegenContext<LlvmCodegenBackend>,
|
||||
msg: String,
|
||||
level: llvm::DiagnosticLevel,
|
||||
mut cookie: u64,
|
||||
cookie: u64,
|
||||
source: Option<(String, Vec<InnerSpan>)>,
|
||||
) {
|
||||
// In LTO build we may get srcloc values from other crates which are invalid
|
||||
// since they use a different source map. To be safe we just suppress these
|
||||
// in LTO builds.
|
||||
if matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
|
||||
cookie = 0;
|
||||
}
|
||||
let span = if cookie == 0 || matches!(cgcx.lto, Lto::Fat | Lto::Thin) {
|
||||
SpanData::default()
|
||||
} else {
|
||||
let lo = BytePos::from_u32(cookie as u32);
|
||||
let hi = BytePos::from_u32((cookie >> 32) as u32);
|
||||
SpanData {
|
||||
lo,
|
||||
// LLVM version < 19 silently truncates the cookie to 32 bits in some situations.
|
||||
hi: if hi.to_u32() != 0 { hi } else { lo },
|
||||
ctxt: SyntaxContext::root(),
|
||||
parent: None,
|
||||
}
|
||||
};
|
||||
let level = match level {
|
||||
llvm::DiagnosticLevel::Error => Level::Error,
|
||||
llvm::DiagnosticLevel::Warning => Level::Warning,
|
||||
llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
|
||||
};
|
||||
cgcx.diag_emitter.inline_asm_error(cookie.try_into().unwrap(), msg, level, source);
|
||||
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
|
||||
cgcx.diag_emitter.inline_asm_error(span, msg, level, source);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
|
||||
|
|
|
@ -151,7 +151,7 @@ impl InlineAsmDiagnostic {
|
|||
unsafe { SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)) };
|
||||
InlineAsmDiagnostic {
|
||||
level: smdiag.level,
|
||||
cookie: cookie.into(),
|
||||
cookie,
|
||||
message: smdiag.message,
|
||||
source: smdiag.source,
|
||||
}
|
||||
|
|
|
@ -2316,7 +2316,7 @@ unsafe extern "C" {
|
|||
|
||||
pub fn LLVMRustGetSMDiagnostic<'a>(
|
||||
DI: &'a DiagnosticInfo,
|
||||
cookie_out: &mut c_uint,
|
||||
cookie_out: &mut u64,
|
||||
) -> &'a SMDiagnostic;
|
||||
|
||||
pub fn LLVMRustUnpackSMDiagnostic(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue