summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp60
-rw-r--r--llvm/lib/MC/MCContext.cpp14
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp15
3 files changed, 47 insertions, 42 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 57864e4e4d4..165b8eea094 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -40,19 +40,12 @@ using namespace llvm;
#define DEBUG_TYPE "asm-printer"
-namespace {
- struct SrcMgrDiagInfo {
- const MDNode *LocInfo;
- LLVMContext::InlineAsmDiagHandlerTy DiagHandler;
- void *DiagContext;
- };
-}
-
/// srcMgrDiagHandler - This callback is invoked when the SourceMgr for an
/// inline asm has an error in it. diagInfo is a pointer to the SrcMgrDiagInfo
/// struct above.
static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) {
- SrcMgrDiagInfo *DiagInfo = static_cast<SrcMgrDiagInfo *>(diagInfo);
+ AsmPrinter::SrcMgrDiagInfo *DiagInfo =
+ static_cast<AsmPrinter::SrcMgrDiagInfo *>(diagInfo);
assert(DiagInfo && "Diagnostic context not passed down?");
// If the inline asm had metadata associated with it, pull out a location
@@ -99,35 +92,34 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
return;
}
- SourceMgr SrcMgr;
- SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
+ if (!DiagInfo) {
+ DiagInfo = make_unique<SrcMgrDiagInfo>();
- SrcMgrDiagInfo DiagInfo;
-
- // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
- LLVMContext &LLVMCtx = MMI->getModule()->getContext();
- bool HasDiagHandler = false;
- if (LLVMCtx.getInlineAsmDiagnosticHandler() != nullptr) {
- // If the source manager has an issue, we arrange for srcMgrDiagHandler
- // to be invoked, getting DiagInfo passed into it.
- DiagInfo.LocInfo = LocMDNode;
- DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
- DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
- SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo);
- HasDiagHandler = true;
+ MCContext &Context = MMI->getContext();
+ Context.setInlineSourceManager(&DiagInfo->SrcMgr);
+
+ LLVMContext &LLVMCtx = MMI->getModule()->getContext();
+ if (LLVMCtx.getInlineAsmDiagnosticHandler()) {
+ DiagInfo->DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
+ DiagInfo->DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
+ DiagInfo->SrcMgr.setDiagHandler(srcMgrDiagHandler, DiagInfo.get());
+ }
}
+ SourceMgr &SrcMgr = DiagInfo->SrcMgr;
+ SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
+ DiagInfo->LocInfo = LocMDNode;
+
std::unique_ptr<MemoryBuffer> Buffer;
- if (isNullTerminated)
- Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
- else
- Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
+ // The inline asm source manager will outlive Str, so make a copy of the
+ // string for SourceMgr to own.
+ Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
// Tell SrcMgr about this buffer, it takes ownership of the buffer.
- SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+ unsigned BufNum = SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
std::unique_ptr<MCAsmParser> Parser(
- createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI));
+ createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));
// We create a new MCInstrInfo here since we might be at the module level
// and not have a MachineFunction to initialize the TargetInstrInfo from and
@@ -151,7 +143,13 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
int Res = Parser->Run(/*NoInitialTextSection*/ true,
/*NoFinalize*/ true);
emitInlineAsmEnd(STI, &TAP->getSTI());
- if (Res && !HasDiagHandler)
+
+ // LocInfo cannot be used for error generation from the backend.
+ // FIXME: associate LocInfo with the SourceBuffer to improve backend
+ // messages.
+ DiagInfo->LocInfo = nullptr;
+
+ if (Res && !DiagInfo->DiagHandler)
report_fatal_error("Error parsing inline asm\n");
}
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 16c2c99be67..2bfd8e55cad 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -521,13 +521,15 @@ CodeViewContext &MCContext::getCVContext() {
void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
HadError = true;
- // If we have a source manager use it. Otherwise just use the generic
- // report_fatal_error().
- if (!SrcMgr)
+ // If we have a source manager use it. Otherwise, try using the inline source
+ // manager.
+ // If that fails, use the generic report_fatal_error().
+ if (SrcMgr)
+ SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+ else if (InlineSrcMgr)
+ InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+ else
report_fatal_error(Msg, false);
-
- // Use the source manager to print the message.
- SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
}
void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index f714aeef054..f71e05107d7 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -209,7 +209,7 @@ private:
public:
AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
- const MCAsmInfo &MAI);
+ const MCAsmInfo &MAI, unsigned CB);
~AsmParser() override;
bool Run(bool NoInitialTextSection, bool NoFinalize = false) override;
@@ -572,9 +572,9 @@ extern MCAsmParserExtension *createCOFFAsmParser();
enum { DEFAULT_ADDRSPACE = 0 };
AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
- const MCAsmInfo &MAI)
+ const MCAsmInfo &MAI, unsigned CB = 0)
: Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM),
- PlatformParser(nullptr), CurBuffer(SM.getMainFileID()),
+ PlatformParser(nullptr), CurBuffer(CB ? CB : SM.getMainFileID()),
MacrosEnabledFlag(true), CppHashInfo(), AssemblerDialect(~0U),
IsDarwin(false), ParsingInlineAsm(false) {
HadError = false;
@@ -608,6 +608,10 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
AsmParser::~AsmParser() {
assert((HadError || ActiveMacros.empty()) &&
"Unexpected active macro instantiation!");
+
+ // Restore the saved diagnostics handler and context for use during
+ // finalization.
+ SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext);
}
void AsmParser::printMacroInstantiations() {
@@ -5520,6 +5524,7 @@ bool parseAssignmentExpression(StringRef Name, bool allow_redef,
/// \brief Create an MCAsmParser instance.
MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C,
- MCStreamer &Out, const MCAsmInfo &MAI) {
- return new AsmParser(SM, C, Out, MAI);
+ MCStreamer &Out, const MCAsmInfo &MAI,
+ unsigned CB) {
+ return new AsmParser(SM, C, Out, MAI, CB);
}
OpenPOWER on IntegriCloud