[llvm] Improving ThinLTO error message for inline assembly errors (PR #102211)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 13 15:15:42 PDT 2024
https://github.com/HighW4y2H3ll updated https://github.com/llvm/llvm-project/pull/102211
>From e296c87a572469da6e4097b9887ac6cbf936f3b4 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Fri, 2 Aug 2024 17:26:47 -0700
Subject: [PATCH 1/7] fix wrong inline assembly line/col info in the error
message with ThinLTO
---
llvm/include/llvm/CodeGen/AsmPrinter.h | 6 ++++--
llvm/include/llvm/Support/SourceMgr.h | 10 ++++++++++
.../CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 15 ++++++++++-----
llvm/lib/Support/SourceMgr.cpp | 13 +++++++++++--
4 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 36d1b479738704..88f437b1efaa79 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -877,7 +877,8 @@ class AsmPrinter : public MachineFunctionPass {
emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
const MCTargetOptions &MCOptions,
const MDNode *LocMDNode = nullptr,
- InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
+ InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT,
+ const DebugLoc *DbgLoc = nullptr) const;
/// This method formats and emits the specified machine instruction that is an
/// inline asm.
@@ -886,7 +887,8 @@ class AsmPrinter : public MachineFunctionPass {
/// Add inline assembly info to the diagnostics machinery, so we can
/// emit file and position info. Returns SrcMgr memory buffer position.
unsigned addInlineAsmDiagBuffer(StringRef AsmStr,
- const MDNode *LocMDNode) const;
+ const MDNode *LocMDNode,
+ const DebugLoc *DbgLoc) const;
//===------------------------------------------------------------------===//
// Internal Implementation Details
diff --git a/llvm/include/llvm/Support/SourceMgr.h b/llvm/include/llvm/Support/SourceMgr.h
index 7a4b6de1162da4..167ccb8a4810de 100644
--- a/llvm/include/llvm/Support/SourceMgr.h
+++ b/llvm/include/llvm/Support/SourceMgr.h
@@ -59,6 +59,9 @@ class SourceMgr {
/// dynamically based on the size of Buffer.
mutable void *OffsetCache = nullptr;
+ // Base Source LineNo and Column where this Buffer starts
+ unsigned BaseLine, BaseCol;
+
/// Look up a given \p Ptr in the buffer, determining which line it came
/// from.
unsigned getLineNumber(const char *Ptr) const;
@@ -143,9 +146,16 @@ class SourceMgr {
/// the memory buffer.
unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
SMLoc IncludeLoc) {
+ return AddNewSourceBuffer(std::move(F), 0, 0, IncludeLoc);
+ }
+ unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
+ unsigned Line, unsigned Col,
+ SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = std::move(F);
NB.IncludeLoc = IncludeLoc;
+ NB.BaseLine = Line;
+ NB.BaseCol = Col;
Buffers.push_back(std::move(NB));
return Buffers.size();
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 6fe8d0e0af9951..0f62269aeb334d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -43,7 +43,8 @@ using namespace llvm;
#define DEBUG_TYPE "asm-printer"
unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
- const MDNode *LocMDNode) const {
+ const MDNode *LocMDNode,
+ const DebugLoc *DbgLoc) const {
MCContext &Context = MMI->getContext();
Context.initInlineSourceManager();
SourceMgr &SrcMgr = *Context.getInlineSourceManager();
@@ -55,7 +56,9 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
- unsigned BufNum = SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+ unsigned BufNum = DbgLoc ? \
+ SrcMgr.AddNewSourceBuffer(std::move(Buffer), DbgLoc->getLine()-1, DbgLoc->getCol()-1, SMLoc()) : \
+ SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
// Store LocMDNode in DiagInfo, using BufNum as an identifier.
if (LocMDNode) {
@@ -71,7 +74,8 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
const MCTargetOptions &MCOptions,
const MDNode *LocMDNode,
- InlineAsm::AsmDialect Dialect) const {
+ InlineAsm::AsmDialect Dialect,
+ const DebugLoc *DbgLoc) const {
assert(!Str.empty() && "Can't emit empty inline asm block");
// Remember if the buffer is nul terminated or not so we can avoid a copy.
@@ -95,7 +99,7 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
return;
}
- unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode);
+ unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode, DbgLoc);
SourceMgr &SrcMgr = *MMI->getContext().getInlineSourceManager();
SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
@@ -415,8 +419,9 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
}
}
+ const DebugLoc &DbgLoc = MI->getDebugLoc();
emitInlineAsm(StringData, getSubtargetInfo(), TM.Options.MCOptions, LocMD,
- MI->getInlineAsmDialect());
+ MI->getInlineAsmDialect(), DbgLoc ? &DbgLoc : nullptr);
// Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't
// enabled, so we use emitRawComment.
diff --git a/llvm/lib/Support/SourceMgr.cpp b/llvm/lib/Support/SourceMgr.cpp
index 3f97213d86c055..4a8355bd8e9346 100644
--- a/llvm/lib/Support/SourceMgr.cpp
+++ b/llvm/lib/Support/SourceMgr.cpp
@@ -114,7 +114,7 @@ unsigned SourceMgr::SrcBuffer::getLineNumberSpecialized(const char *Ptr) const {
// llvm::lower_bound gives the number of EOL before PtrOffset. Add 1 to get
// the line number.
- return llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
+ return BaseLine + llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
}
/// Look up a given \p Ptr in the buffer, determining which line it came
@@ -137,6 +137,10 @@ const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
std::vector<T> &Offsets =
GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
+ // Offset the LineNo where the Buffer starts
+ if (LineNo >= BaseLine)
+ LineNo -= BaseLine;
+
// We start counting line and column numbers from 1.
if (LineNo != 0)
--LineNo;
@@ -169,6 +173,7 @@ SourceMgr::SrcBuffer::getPointerForLineNumber(unsigned LineNo) const {
SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&Other)
: Buffer(std::move(Other.Buffer)), OffsetCache(Other.OffsetCache),
+ BaseLine(Other.BaseLine), BaseCol(Other.BaseCol),
IncludeLoc(Other.IncludeLoc) {
Other.OffsetCache = nullptr;
}
@@ -202,7 +207,7 @@ SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
size_t NewlineOffs = StringRef(BufStart, Ptr - BufStart).find_last_of("\n\r");
if (NewlineOffs == StringRef::npos)
NewlineOffs = ~(size_t)0;
- return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs);
+ return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs + SB.BaseCol);
}
// FIXME: Note that the formatting of source locations is spread between
@@ -238,6 +243,10 @@ SMLoc SourceMgr::FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
if (!Ptr)
return SMLoc();
+ // Offset the ColNo where Buffer starts
+ if (ColNo >= SB.BaseCol)
+ ColNo -= SB.BaseCol;
+
// We start counting line and column numbers from 1.
if (ColNo != 0)
--ColNo;
>From b706152156cd75a003d3e61ff1656a2694489cc0 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Wed, 7 Aug 2024 16:35:44 -0700
Subject: [PATCH 2/7] include source filename
---
llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 0f62269aeb334d..b784856e6d246d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -22,6 +22,7 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/LLVMContext.h"
@@ -50,10 +51,11 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
SourceMgr &SrcMgr = *Context.getInlineSourceManager();
std::vector<const MDNode *> &LocInfos = Context.getLocInfos();
+ DIScope *Scope = DbgLoc ? dyn_cast<DIScope>(DbgLoc->getScope()) : nullptr;
std::unique_ptr<MemoryBuffer> Buffer;
// The inline asm source manager will outlive AsmStr, so make a copy of the
// string for SourceMgr to own.
- Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, "<inline asm>");
+ Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename() : "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
unsigned BufNum = DbgLoc ? \
>From c1bca4ca33a17970e7ba36b4130f547957721db5 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Wed, 7 Aug 2024 16:36:02 -0700
Subject: [PATCH 3/7] add testcase
---
.../CodeGen/Generic/inline-asm-debuginfo.c | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
new file mode 100644
index 00000000000000..e6856344c02758
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -0,0 +1,33 @@
+// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o /dev/stdout | llc -o /dev/null 2>&1 | FileCheck %s
+void bad_asm() {
+ asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:3:16: error: unknown token in expression
+}
+
+void good_asm() {
+ asm volatile ("movq $0xdeadbeef, %rax");
+}
+
+void bad_multi_asm() {
+ asm ( "movl $10, %eax;"
+ "BAD SYNTAX;" // CHECK: inline-asm-debuginfo.c:11:19: error: invalid instruction mnemonic 'bad'
+ "subl %ebx, %eax;" );
+}
+
+void bad_multi_asm_linechg() {
+ asm ( "movl $10, %eax;\n"
+ "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:18:3: error: invalid instruction mnemonic 'bad'
+ "subl %ebx, %eax;\n" );
+}
+
+void good_multi_asm_linechg() {
+ asm ( "movl $10, %eax;\n"
+ "test %rax, %rax;\n"
+ "subl %ebx, %eax;\n" );
+}
+
+void bad_multi_asm_op() {
+ unsigned val=1, i=0;
+ asm ( "movl %1, %%eax;\n"
+ "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:31:3: error: invalid instruction mnemonic 'bad'
+ "subl %0, %%eax;\n" : "=r" (val) : "r" (i) : );
+}
>From c9f092a3e35b1a5ba91518a29fe612fdb34fb246 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Wed, 7 Aug 2024 17:05:09 -0700
Subject: [PATCH 4/7] make clang-format happy
---
llvm/include/llvm/CodeGen/AsmPrinter.h | 14 ++++++--------
llvm/include/llvm/Support/SourceMgr.h | 5 ++---
.../lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 12 +++++++-----
3 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 88f437b1efaa79..7897bcabed02d8 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -873,12 +873,11 @@ class AsmPrinter : public MachineFunctionPass {
void emitFunctionPrefix(ArrayRef<const Constant *> Prefix);
/// Emit a blob of inline asm to the output streamer.
- void
- emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
- const MCTargetOptions &MCOptions,
- const MDNode *LocMDNode = nullptr,
- InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT,
- const DebugLoc *DbgLoc = nullptr) const;
+ void emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
+ const MCTargetOptions &MCOptions,
+ const MDNode *LocMDNode = nullptr,
+ InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT,
+ const DebugLoc *DbgLoc = nullptr) const;
/// This method formats and emits the specified machine instruction that is an
/// inline asm.
@@ -886,8 +885,7 @@ class AsmPrinter : public MachineFunctionPass {
/// Add inline assembly info to the diagnostics machinery, so we can
/// emit file and position info. Returns SrcMgr memory buffer position.
- unsigned addInlineAsmDiagBuffer(StringRef AsmStr,
- const MDNode *LocMDNode,
+ unsigned addInlineAsmDiagBuffer(StringRef AsmStr, const MDNode *LocMDNode,
const DebugLoc *DbgLoc) const;
//===------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/Support/SourceMgr.h b/llvm/include/llvm/Support/SourceMgr.h
index 167ccb8a4810de..6a0ef62c252c5d 100644
--- a/llvm/include/llvm/Support/SourceMgr.h
+++ b/llvm/include/llvm/Support/SourceMgr.h
@@ -148,9 +148,8 @@ class SourceMgr {
SMLoc IncludeLoc) {
return AddNewSourceBuffer(std::move(F), 0, 0, IncludeLoc);
}
- unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
- unsigned Line, unsigned Col,
- SMLoc IncludeLoc) {
+ unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F, unsigned Line,
+ unsigned Col, SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = std::move(F);
NB.IncludeLoc = IncludeLoc;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index b784856e6d246d..67dec6678c4ce8 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -55,12 +55,15 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
std::unique_ptr<MemoryBuffer> Buffer;
// The inline asm source manager will outlive AsmStr, so make a copy of the
// string for SourceMgr to own.
- Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename() : "<inline asm>");
+ Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename()
+ : "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
- unsigned BufNum = DbgLoc ? \
- SrcMgr.AddNewSourceBuffer(std::move(Buffer), DbgLoc->getLine()-1, DbgLoc->getCol()-1, SMLoc()) : \
- SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+ unsigned BufNum =
+ DbgLoc
+ ? SrcMgr.AddNewSourceBuffer(std::move(Buffer), DbgLoc->getLine() - 1,
+ DbgLoc->getCol() - 1, SMLoc())
+ : SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
// Store LocMDNode in DiagInfo, using BufNum as an identifier.
if (LocMDNode) {
@@ -71,7 +74,6 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
return BufNum;
}
-
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
const MCTargetOptions &MCOptions,
>From 53e8ae9f08d87d7247e5a8a6a4a504a86f8dbf6f Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Thu, 8 Aug 2024 23:09:45 -0700
Subject: [PATCH 5/7] simplify testcase
---
.../CodeGen/Generic/inline-asm-debuginfo.c | 34 +++++--------------
1 file changed, 9 insertions(+), 25 deletions(-)
diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
index e6856344c02758..b60e465fbc5ae1 100644
--- a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -1,33 +1,17 @@
-// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o /dev/stdout | llc -o /dev/null 2>&1 | FileCheck %s
+// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o %t
+// RUN: llc %t 2>&1 | FileCheck %s
void bad_asm() {
- asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:3:16: error: unknown token in expression
-}
-
-void good_asm() {
- asm volatile ("movq $0xdeadbeef, %rax");
+ asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: error: unknown token in expression
}
void bad_multi_asm() {
- asm ( "movl $10, %eax;"
- "BAD SYNTAX;" // CHECK: inline-asm-debuginfo.c:11:19: error: invalid instruction mnemonic 'bad'
- "subl %ebx, %eax;" );
+ asm ( ";"
+ "BAD SYNTAX;" // CHECK: inline-asm-debuginfo.c:8:5: error: invalid instruction mnemonic 'bad'
+ ";" );
}
void bad_multi_asm_linechg() {
- asm ( "movl $10, %eax;\n"
- "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:18:3: error: invalid instruction mnemonic 'bad'
- "subl %ebx, %eax;\n" );
-}
-
-void good_multi_asm_linechg() {
- asm ( "movl $10, %eax;\n"
- "test %rax, %rax;\n"
- "subl %ebx, %eax;\n" );
-}
-
-void bad_multi_asm_op() {
- unsigned val=1, i=0;
- asm ( "movl %1, %%eax;\n"
- "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:31:3: error: invalid instruction mnemonic 'bad'
- "subl %0, %%eax;\n" : "=r" (val) : "r" (i) : );
+ asm ( ";\n"
+ "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:15:3: error: invalid instruction mnemonic 'bad'
+ ";\n" );
}
>From 58d20c38b760c980469abdb1406383b29330aeb5 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Mon, 12 Aug 2024 21:35:33 -0700
Subject: [PATCH 6/7] use clang style error message for inline assembly
---
llvm/include/llvm/Support/SourceMgr.h | 29 ++++++++--
.../AsmPrinter/AsmPrinterInlineAsm.cpp | 8 +--
llvm/lib/Support/SourceMgr.cpp | 56 ++++++++++++++-----
.../CodeGen/Generic/inline-asm-debuginfo.c | 6 +-
4 files changed, 75 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/Support/SourceMgr.h b/llvm/include/llvm/Support/SourceMgr.h
index 6a0ef62c252c5d..e7239f54c5b4b5 100644
--- a/llvm/include/llvm/Support/SourceMgr.h
+++ b/llvm/include/llvm/Support/SourceMgr.h
@@ -61,6 +61,7 @@ class SourceMgr {
// Base Source LineNo and Column where this Buffer starts
unsigned BaseLine, BaseCol;
+ StringRef SourceFilename;
/// Look up a given \p Ptr in the buffer, determining which line it came
/// from.
@@ -146,15 +147,16 @@ class SourceMgr {
/// the memory buffer.
unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
SMLoc IncludeLoc) {
- return AddNewSourceBuffer(std::move(F), 0, 0, IncludeLoc);
+ return AddNewSourceBuffer(std::move(F), "", 0, 0, IncludeLoc);
}
- unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F, unsigned Line,
- unsigned Col, SMLoc IncludeLoc) {
+ unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F, StringRef SrcFN,
+ unsigned Line, unsigned Col, SMLoc IncludeLoc) {
SrcBuffer NB;
NB.Buffer = std::move(F);
NB.IncludeLoc = IncludeLoc;
NB.BaseLine = Line;
NB.BaseCol = Col;
+ NB.SourceFilename = SrcFN;
Buffers.push_back(std::move(NB));
return Buffers.size();
}
@@ -210,6 +212,11 @@ class SourceMgr {
/// specified file. This is not a fast method.
std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
unsigned BufferID = 0) const;
+ /// Similiar to `getLineAndColumn` but propagates debug info
+ std::pair<unsigned, unsigned>
+ getDebugLineAndColumn(SMLoc Loc, unsigned BufferID = 0) const;
+ /// Get the source filename from debug info, return "" if no debug info found
+ StringRef getDebugFilename(SMLoc Loc, unsigned BufferID = 0) const;
/// Get a string with the \p SMLoc filename and line number
/// formatted in the standard style.
@@ -293,6 +300,9 @@ class SMDiagnostic {
std::string Filename;
int LineNo = 0;
int ColumnNo = 0;
+ std::string SrcFilename;
+ int SrcLineNo = 0;
+ int SrcColumnNo = 0;
SourceMgr::DiagKind Kind = SourceMgr::DK_Error;
std::string Message, LineContents;
std::vector<std::pair<unsigned, unsigned>> Ranges;
@@ -303,13 +313,24 @@ class SMDiagnostic {
SMDiagnostic() = default;
// Diagnostic with no location (e.g. file not found, command line arg error).
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
- : Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {}
+ : Filename(filename), LineNo(-1), ColumnNo(-1), SrcFilename(filename),
+ SrcLineNo(-1), SrcColumnNo(-1), Kind(Knd), Message(Msg) {}
// Diagnostic with a location.
SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col,
SourceMgr::DiagKind Kind, StringRef Msg, StringRef LineStr,
ArrayRef<std::pair<unsigned, unsigned>> Ranges,
ArrayRef<SMFixIt> FixIts = {});
+ SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col,
+ StringRef SrcFN, int SrcLine, int SrcCol,
+ SourceMgr::DiagKind Kind, StringRef Msg, StringRef LineStr,
+ ArrayRef<std::pair<unsigned, unsigned>> Ranges,
+ ArrayRef<SMFixIt> FixIts = {})
+ : SMDiagnostic(sm, L, FN, Line, Col, Kind, Msg, LineStr, Ranges, FixIts) {
+ SrcFilename = std::string(SrcFN);
+ SrcLineNo = SrcLine;
+ SrcColumnNo = SrcCol;
+ }
const SourceMgr *getSourceMgr() const { return SM; }
SMLoc getLoc() const { return Loc; }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 67dec6678c4ce8..00520e8b89487b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -55,13 +55,13 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
std::unique_ptr<MemoryBuffer> Buffer;
// The inline asm source manager will outlive AsmStr, so make a copy of the
// string for SourceMgr to own.
- Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename()
- : "<inline asm>");
+ Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
unsigned BufNum =
- DbgLoc
- ? SrcMgr.AddNewSourceBuffer(std::move(Buffer), DbgLoc->getLine() - 1,
+ (DbgLoc && Scope)
+ ? SrcMgr.AddNewSourceBuffer(std::move(Buffer), Scope->getFilename(),
+ DbgLoc->getLine() - 1,
DbgLoc->getCol() - 1, SMLoc())
: SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
diff --git a/llvm/lib/Support/SourceMgr.cpp b/llvm/lib/Support/SourceMgr.cpp
index 4a8355bd8e9346..dd4900d0bc8d70 100644
--- a/llvm/lib/Support/SourceMgr.cpp
+++ b/llvm/lib/Support/SourceMgr.cpp
@@ -114,7 +114,7 @@ unsigned SourceMgr::SrcBuffer::getLineNumberSpecialized(const char *Ptr) const {
// llvm::lower_bound gives the number of EOL before PtrOffset. Add 1 to get
// the line number.
- return BaseLine + llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
+ return llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
}
/// Look up a given \p Ptr in the buffer, determining which line it came
@@ -137,10 +137,6 @@ const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
std::vector<T> &Offsets =
GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
- // Offset the LineNo where the Buffer starts
- if (LineNo >= BaseLine)
- LineNo -= BaseLine;
-
// We start counting line and column numbers from 1.
if (LineNo != 0)
--LineNo;
@@ -174,7 +170,7 @@ SourceMgr::SrcBuffer::getPointerForLineNumber(unsigned LineNo) const {
SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&Other)
: Buffer(std::move(Other.Buffer)), OffsetCache(Other.OffsetCache),
BaseLine(Other.BaseLine), BaseCol(Other.BaseCol),
- IncludeLoc(Other.IncludeLoc) {
+ SourceFilename(Other.SourceFilename), IncludeLoc(Other.IncludeLoc) {
Other.OffsetCache = nullptr;
}
@@ -193,6 +189,29 @@ SourceMgr::SrcBuffer::~SrcBuffer() {
}
}
+StringRef SourceMgr::getDebugFilename(SMLoc Loc, unsigned BufferID) const {
+ if (!BufferID)
+ BufferID = FindBufferContainingLoc(Loc);
+ assert(BufferID && "Invalid location!");
+
+ auto &SB = getBufferInfo(BufferID);
+
+ return SB.SourceFilename;
+}
+
+std::pair<unsigned, unsigned>
+SourceMgr::getDebugLineAndColumn(SMLoc Loc, unsigned BufferID) const {
+ if (!BufferID)
+ BufferID = FindBufferContainingLoc(Loc);
+ assert(BufferID && "Invalid location!");
+
+ auto &SB = getBufferInfo(BufferID);
+
+ std::pair<unsigned, unsigned> LineAndCol = getLineAndColumn(Loc, BufferID);
+ return std::make_pair(SB.BaseLine + LineAndCol.first,
+ SB.BaseCol + LineAndCol.second);
+}
+
std::pair<unsigned, unsigned>
SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
if (!BufferID)
@@ -207,7 +226,7 @@ SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
size_t NewlineOffs = StringRef(BufStart, Ptr - BufStart).find_last_of("\n\r");
if (NewlineOffs == StringRef::npos)
NewlineOffs = ~(size_t)0;
- return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs + SB.BaseCol);
+ return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs);
}
// FIXME: Note that the formatting of source locations is spread between
@@ -243,10 +262,6 @@ SMLoc SourceMgr::FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
if (!Ptr)
return SMLoc();
- // Offset the ColNo where Buffer starts
- if (ColNo >= SB.BaseCol)
- ColNo -= SB.BaseCol;
-
// We start counting line and column numbers from 1.
if (ColNo != 0)
--ColNo;
@@ -286,9 +301,10 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
// First thing to do: find the current buffer containing the specified
// location to pull out the source line.
SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges;
- std::pair<unsigned, unsigned> LineAndCol;
+ std::pair<unsigned, unsigned> LineAndCol, DbgLineAndCol;
StringRef BufferID = "<unknown>";
StringRef LineStr;
+ StringRef DbgFN;
if (Loc.isValid()) {
unsigned CurBuf = FindBufferContainingLoc(Loc);
@@ -334,10 +350,13 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
}
LineAndCol = getLineAndColumn(Loc, CurBuf);
+ DbgLineAndCol = getDebugLineAndColumn(Loc, CurBuf);
+ DbgFN = getDebugFilename(Loc, CurBuf);
}
return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
- LineAndCol.second - 1, Kind, Msg.str(), LineStr,
+ LineAndCol.second - 1, DbgFN, DbgLineAndCol.first,
+ DbgLineAndCol.second - 1, Kind, Msg.str(), LineStr,
ColRanges, FixIts);
}
@@ -390,6 +409,7 @@ SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line,
ArrayRef<std::pair<unsigned, unsigned>> Ranges,
ArrayRef<SMFixIt> Hints)
: SM(&sm), Loc(L), Filename(std::string(FN)), LineNo(Line), ColumnNo(Col),
+ SrcFilename(std::string(FN)), SrcLineNo(Line), SrcColumnNo(Col),
Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
FixIts(Hints) {
llvm::sort(FixIts);
@@ -501,6 +521,16 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors,
S << ProgName << ": ";
if (ShowLocation && !Filename.empty()) {
+ if (Filename == "<inline asm>" && !SrcFilename.empty()) {
+ S << SrcFilename;
+ if (SrcLineNo != -1) {
+ S << ':' << SrcLineNo;
+ if (SrcColumnNo != -1)
+ S << ':' << (SrcColumnNo + 1);
+ }
+ S << ": ";
+ }
+
if (Filename == "-")
S << "<stdin>";
else
diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
index b60e465fbc5ae1..20effeb191f449 100644
--- a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -1,17 +1,17 @@
// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o %t
// RUN: llc %t 2>&1 | FileCheck %s
void bad_asm() {
- asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: error: unknown token in expression
+ asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: <inline asm>:1:14: error: unknown token in expression
}
void bad_multi_asm() {
asm ( ";"
- "BAD SYNTAX;" // CHECK: inline-asm-debuginfo.c:8:5: error: invalid instruction mnemonic 'bad'
+ "BAD SYNTAX;" // CHECK: inline-asm-debuginfo.c:8:5: <inline asm>:1:3: error: invalid instruction mnemonic 'bad'
";" );
}
void bad_multi_asm_linechg() {
asm ( ";\n"
- "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:15:3: error: invalid instruction mnemonic 'bad'
+ "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:15:3: <inline asm>:2:1: error: invalid instruction mnemonic 'bad'
";\n" );
}
>From 65949a83be2bd05221f0871b1de65de7ca565217 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Tue, 13 Aug 2024 14:57:37 -0700
Subject: [PATCH 7/7] more portable way to disable pipefail
---
llvm/test/CodeGen/Generic/inline-asm-debuginfo.c | 2 +-
llvm/test/CodeGen/Generic/lit.local.cfg | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
index 20effeb191f449..3986034caa3ec8 100644
--- a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -1,4 +1,4 @@
-// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o %t
+// RUN: clang -emit-llvm -c %s -g -o %t
// RUN: llc %t 2>&1 | FileCheck %s
void bad_asm() {
asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: <inline asm>:1:14: error: unknown token in expression
diff --git a/llvm/test/CodeGen/Generic/lit.local.cfg b/llvm/test/CodeGen/Generic/lit.local.cfg
index 1eae465c12545f..873068862fbbb9 100644
--- a/llvm/test/CodeGen/Generic/lit.local.cfg
+++ b/llvm/test/CodeGen/Generic/lit.local.cfg
@@ -1,2 +1,3 @@
if not config.target_triple:
config.unsupported = True
+config.pipefail = False
More information about the llvm-commits
mailing list