ychen updated this revision to Diff 326597.
ychen added a comment.

- Refrain from including SourceMgr.h in MCContext.h


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97449/new/

https://reviews.llvm.org/D97449

Files:
  clang/lib/CodeGen/CodeGenAction.cpp
  lldb/source/Expression/IRExecutionUnit.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/IR/DiagnosticInfo.h
  llvm/include/llvm/IR/LLVMContext.h
  llvm/include/llvm/MC/MCContext.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
  llvm/lib/CodeGen/MachineModuleInfo.cpp
  llvm/lib/IR/LLVMContext.cpp
  llvm/lib/IR/LLVMContextImpl.h
  llvm/lib/MC/MCContext.cpp
  llvm/lib/MC/MCParser/AsmParser.cpp
  llvm/test/CodeGen/AMDGPU/lds-initializer.ll
  llvm/test/CodeGen/AMDGPU/lds-zero-initializer.ll
  llvm/test/CodeGen/XCore/section-name.ll
  llvm/tools/llc/llc.cpp

Index: llvm/tools/llc/llc.cpp
===================================================================
--- llvm/tools/llc/llc.cpp
+++ llvm/tools/llc/llc.cpp
@@ -290,6 +290,22 @@
   bool *HasError;
   LLCDiagnosticHandler(bool *HasErrorPtr) : HasError(HasErrorPtr) {}
   bool handleDiagnostics(const DiagnosticInfo &DI) override {
+    if (DI.getKind() == llvm::DK_SrcMgr) {
+      const auto &DISM = cast<DiagnosticInfoSrcMgr>(DI);
+      const SMDiagnostic &SMD = DISM.getSMDiag();
+
+      if (SMD.getKind() == SourceMgr::DK_Error)
+        *HasError = true;
+
+      SMD.print(nullptr, errs());
+
+      // For testing purposes, we print the LocCookie here.
+      if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
+        WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
+
+      return true;
+    }
+
     if (DI.getSeverity() == DS_Error)
       *HasError = true;
 
@@ -305,19 +321,6 @@
   }
 };
 
-static void InlineAsmDiagHandler(const SMDiagnostic &SMD, void *Context,
-                                 unsigned LocCookie) {
-  bool *HasError = static_cast<bool *>(Context);
-  if (SMD.getKind() == SourceMgr::DK_Error)
-    *HasError = true;
-
-  SMD.print(nullptr, errs());
-
-  // For testing purposes, we print the LocCookie here.
-  if (LocCookie)
-    WithColor::note() << "!srcloc = " << LocCookie << "\n";
-}
-
 // main - Entry point for the llc compiler.
 //
 int main(int argc, char **argv) {
@@ -367,7 +370,6 @@
   bool HasError = false;
   Context.setDiagnosticHandler(
       std::make_unique<LLCDiagnosticHandler>(&HasError));
-  Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError);
 
   Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
       setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
Index: llvm/test/CodeGen/XCore/section-name.ll
===================================================================
--- llvm/test/CodeGen/XCore/section-name.ll
+++ llvm/test/CodeGen/XCore/section-name.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=xcore -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc < %s -march=xcore -o /dev/null 2>&1 | FileCheck %s
 
 @bar = internal global i32 zeroinitializer
 
Index: llvm/test/CodeGen/AMDGPU/lds-zero-initializer.ll
===================================================================
--- llvm/test/CodeGen/AMDGPU/lds-zero-initializer.ll
+++ llvm/test/CodeGen/AMDGPU/lds-zero-initializer.ll
@@ -1,5 +1,5 @@
-; RUN: llc -march=amdgcn -mcpu=tahiti < %s -o /dev/null 2>&1 | FileCheck %s
-; RUN: llc -march=amdgcn -mcpu=tonga < %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=tahiti < %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=tonga < %s -o /dev/null 2>&1 | FileCheck %s
 
 ; CHECK: lds: unsupported initializer for address space
 
Index: llvm/test/CodeGen/AMDGPU/lds-initializer.ll
===================================================================
--- llvm/test/CodeGen/AMDGPU/lds-initializer.ll
+++ llvm/test/CodeGen/AMDGPU/lds-initializer.ll
@@ -1,5 +1,5 @@
-; RUN: llc -march=amdgcn -mcpu=tahiti < %s -o /dev/null 2>&1 | FileCheck %s
-; RUN: llc -march=amdgcn -mcpu=tonga < %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=tahiti < %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc -march=amdgcn -mcpu=tonga < %s -o /dev/null 2>&1 | FileCheck %s
 
 ; CHECK: lds: unsupported initializer for address space
 
Index: llvm/lib/MC/MCParser/AsmParser.cpp
===================================================================
--- llvm/lib/MC/MCParser/AsmParser.cpp
+++ llvm/lib/MC/MCParser/AsmParser.cpp
@@ -54,6 +54,7 @@
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -892,6 +893,8 @@
 }
 
 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
+  SaveAndRestore<bool> TurnOnAsmParseDiag(Ctx.AsmParseMode, true);
+
   // Create the initial section, if requested.
   if (!NoInitialTextSection)
     Out.InitSections(false);
@@ -2348,7 +2351,7 @@
 /// will use the last parsed cpp hash line filename comment
 /// for the Filename and LineNo if any in the diagnostic.
 void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
-  const AsmParser *Parser = static_cast<const AsmParser *>(Context);
+  auto *Parser = static_cast<AsmParser *>(Context);
   raw_ostream &OS = errs();
 
   const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
@@ -2369,12 +2372,8 @@
   // If we have not parsed a cpp hash line filename comment or the source
   // manager changed or buffer changed (like in a nested include) then just
   // print the normal diagnostic using its Filename and LineNo.
-  if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr ||
-      DiagBuf != CppHashBuf) {
-    if (Parser->SavedDiagHandler)
-      Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext);
-    else
-      Diag.print(nullptr, OS);
+  if (!Parser->CppHashInfo.LineNumber || DiagBuf != CppHashBuf) {
+    Parser->getContext().diagnose(Diag);
     return;
   }
 
@@ -2393,10 +2392,7 @@
                        Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(),
                        Diag.getLineContents(), Diag.getRanges());
 
-  if (Parser->SavedDiagHandler)
-    Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext);
-  else
-    NewDiag.print(nullptr, OS);
+  Parser->getContext().diagnose(NewDiag);
 }
 
 // FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The
Index: llvm/lib/MC/MCContext.cpp
===================================================================
--- llvm/lib/MC/MCContext.cpp
+++ llvm/lib/MC/MCContext.cpp
@@ -57,11 +57,16 @@
                  "AS_SECURE_LOG_FILE env variable)"),
         cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden);
 
+static void defaultDiagHandler(const SMDiagnostic &SMD, bool, const SourceMgr &,
+                               std::vector<const MDNode *> &) {
+  SMD.print(nullptr, errs());
+}
+
 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
                      const MCObjectFileInfo *mofi, const SourceMgr *mgr,
                      MCTargetOptions const *TargetOpts, bool DoAutoReset)
-    : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri), MOFI(mofi),
-      Symbols(Allocator), UsedNames(Allocator),
+    : SrcMgr(mgr), InlineSrcMgr(nullptr), DiagHandler(defaultDiagHandler),
+      MAI(mai), MRI(mri), MOFI(mofi), Symbols(Allocator), UsedNames(Allocator),
       InlineAsmUsedLabelNames(Allocator),
       CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
       AutoReset(DoAutoReset), TargetOptions(TargetOpts) {
@@ -80,11 +85,22 @@
   // we don't need to free them here.
 }
 
+void MCContext::initInlineSourceManager() {
+  if (!InlineSrcMgr)
+    InlineSrcMgr.reset(new SourceMgr());
+}
+
 //===----------------------------------------------------------------------===//
 // Module Lifetime Management
 //===----------------------------------------------------------------------===//
 
 void MCContext::reset() {
+  SrcMgr = nullptr;
+  InlineSrcMgr.release();
+  LocInfos.clear();
+  DiagHandler = defaultDiagHandler;
+  AsmParseMode = false;
+
   // Call the destructors so the fragments are freed
   COFFAllocator.DestroyAll();
   ELFAllocator.DestroyAll();
@@ -835,37 +851,78 @@
 // Error Reporting
 //===----------------------------------------------------------------------===//
 
-void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
-  HadError = true;
+void MCContext::diagnose(const SMDiagnostic &SMD) {
+  assert(DiagHandler && "MCContext::DiagHandler is not set");
+  bool InlineAsm = false;
+  const SourceMgr *SMP = nullptr;
+  if (SrcMgr) {
+    SMP = SrcMgr;
+  } else if (InlineSrcMgr) {
+    // Fallback to use InlineSrcMgr when SrcMgr is not available.
+    SMP = InlineSrcMgr.get();
+    InlineAsm = true;
+  } else
+    llvm_unreachable("Either SourceMgr should be available");
+  DiagHandler(SMD, InlineAsm, *SMP, LocInfos);
+}
+
+void MCContext::reportCommon(
+    std::function<void(SMDiagnostic &, const SourceMgr *)> GetMessage,
+    bool InlineAsm) {
+  SourceMgr SM;
+  const SourceMgr *SMP = &SM;
+  InlineAsm = InlineAsm || AsmParseMode;
+
+  // FIXME: Simplify these by combining InlineSrcMgr & SrcMgr.
+  //        For MC-only execution, only SrcMgr is used;
+  //        For non MC-only execution, only InlineSrcMgr is used.
+  if (InlineAsm) {
+    if (InlineSrcMgr) {
+      SMP = InlineSrcMgr.get();
+    } else if (SrcMgr) {
+      SMP = SrcMgr;
+      InlineAsm = false;
+    }
+  } else {
+    if (SrcMgr) {
+      SMP = SrcMgr;
+    } else if (InlineSrcMgr) {
+      // Fallback to use InlineSrcMgr when SrcMgr is not available.
+      SMP = InlineSrcMgr.get();
+      InlineAsm = true;
+    }
+  }
 
-  // If we have a source manager use it. Otherwise, try using the inline source
-  // manager.
-  // If that fails, construct a temporary SourceMgr.
-  if (SrcMgr)
-    SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
-  else if (InlineSrcMgr)
-    InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
-  else
-    SourceMgr().PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+  SMDiagnostic D;
+  GetMessage(D, SMP);
+  DiagHandler(D, InlineAsm, *SMP, LocInfos);
 }
 
-void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) {
+void MCContext::reportError(SMLoc Loc, const Twine &Msg, bool InlineAsm) {
+  HadError = true;
+  reportCommon(
+      [&](SMDiagnostic &D, const SourceMgr *SMP) {
+        D = SMP->GetMessage(Loc, SourceMgr::DK_Error, Msg);
+      },
+      InlineAsm);
+}
+
+void MCContext::reportWarning(SMLoc Loc, const Twine &Msg, bool InlineAsm) {
   if (TargetOptions && TargetOptions->MCNoWarn)
     return;
-  if (TargetOptions && TargetOptions->MCFatalWarnings)
-    reportError(Loc, Msg);
-  else {
-    // If we have a source manager use it. Otherwise, try using the inline
-    // source manager.
-    if (SrcMgr)
-      SrcMgr->PrintMessage(Loc, SourceMgr::DK_Warning, Msg);
-    else if (InlineSrcMgr)
-      InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Warning, Msg);
+  if (TargetOptions && TargetOptions->MCFatalWarnings) {
+    reportError(Loc, Msg, InlineAsm);
+  } else {
+    reportCommon(
+        [&](SMDiagnostic &D, const SourceMgr *SMP) {
+          D = SMP->GetMessage(Loc, SourceMgr::DK_Warning, Msg);
+        },
+        InlineAsm);
   }
 }
 
-void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
-  reportError(Loc, Msg);
+void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg, bool InlineAsm) {
+  reportError(Loc, Msg, InlineAsm);
 
   // If we reached here, we are failing ungracefully. Run the interrupt handlers
   // to make sure any special cleanups get done, in particular that we remove
Index: llvm/lib/IR/LLVMContextImpl.h
===================================================================
--- llvm/lib/IR/LLVMContextImpl.h
+++ llvm/lib/IR/LLVMContextImpl.h
@@ -1314,9 +1314,6 @@
   /// will be automatically deleted if this context is deleted.
   SmallPtrSet<Module*, 4> OwnedModules;
 
-  LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler = nullptr;
-  void *InlineAsmDiagContext = nullptr;
-
   /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
   /// frontends, etc.). This should only be used by the specific streamers, and
   /// never directly.
Index: llvm/lib/IR/LLVMContext.cpp
===================================================================
--- llvm/lib/IR/LLVMContext.cpp
+++ llvm/lib/IR/LLVMContext.cpp
@@ -111,26 +111,6 @@
 // Recoverable Backend Errors
 //===----------------------------------------------------------------------===//
 
-void LLVMContext::
-setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
-                              void *DiagContext) {
-  pImpl->InlineAsmDiagHandler = DiagHandler;
-  pImpl->InlineAsmDiagContext = DiagContext;
-}
-
-/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
-/// setInlineAsmDiagnosticHandler.
-LLVMContext::InlineAsmDiagHandlerTy
-LLVMContext::getInlineAsmDiagnosticHandler() const {
-  return pImpl->InlineAsmDiagHandler;
-}
-
-/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
-/// setInlineAsmDiagnosticHandler.
-void *LLVMContext::getInlineAsmDiagnosticContext() const {
-  return pImpl->InlineAsmDiagContext;
-}
-
 void LLVMContext::setDiagnosticHandlerCallBack(
     DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
     void *DiagnosticContext, bool RespectFilters) {
Index: llvm/lib/CodeGen/MachineModuleInfo.cpp
===================================================================
--- llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -16,7 +16,9 @@
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Value.h"
 #include "llvm/IR/ValueHandle.h"
@@ -315,9 +317,44 @@
                 "Machine Module Information", false, false)
 char MachineModuleInfoWrapperPass::ID = 0;
 
+static unsigned getLocCookie(const SMDiagnostic &SMD, const SourceMgr &SrcMgr,
+                             std::vector<const MDNode *> &LocInfos) {
+  // Look up a LocInfo for the buffer this diagnostic is coming from.
+  unsigned BufNum = SrcMgr.FindBufferContainingLoc(SMD.getLoc());
+  const MDNode *LocInfo = nullptr;
+  if (BufNum > 0 && BufNum <= LocInfos.size())
+    LocInfo = LocInfos[BufNum - 1];
+
+  // If the inline asm had metadata associated with it, pull out a location
+  // cookie corresponding to which line the error occurred on.
+  unsigned LocCookie = 0;
+  if (LocInfo) {
+    unsigned ErrorLine = SMD.getLineNo() - 1;
+    if (ErrorLine >= LocInfo->getNumOperands())
+      ErrorLine = 0;
+
+    if (LocInfo->getNumOperands() != 0)
+      if (const ConstantInt *CI =
+              mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
+        LocCookie = CI->getZExtValue();
+  }
+
+  return LocCookie;
+}
+
 bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
   MMI.initialize();
   MMI.TheModule = &M;
+  // FIXME: Do this for new pass manager.
+  LLVMContext &Ctx = M.getContext();
+  MMI.getContext().setDiagnosticHandler(
+      [&Ctx](const SMDiagnostic &SMD, bool IsInlineAsm, const SourceMgr &SrcMgr,
+             std::vector<const MDNode *> &LocInfos) {
+        unsigned LocCookie = 0;
+        if (IsInlineAsm)
+          LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
+        Ctx.diagnose(DiagnosticInfoSrcMgr(SMD, IsInlineAsm, LocCookie));
+      });
   MMI.DbgInfoAvailable = !M.debug_compile_units().empty();
   return false;
 }
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -39,54 +39,12 @@
 
 #define DEBUG_TYPE "asm-printer"
 
-/// 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) {
-  AsmPrinter::SrcMgrDiagInfo *DiagInfo =
-      static_cast<AsmPrinter::SrcMgrDiagInfo *>(diagInfo);
-  assert(DiagInfo && "Diagnostic context not passed down?");
-
-  // Look up a LocInfo for the buffer this diagnostic is coming from.
-  unsigned BufNum = DiagInfo->SrcMgr.FindBufferContainingLoc(Diag.getLoc());
-  const MDNode *LocInfo = nullptr;
-  if (BufNum > 0 && BufNum <= DiagInfo->LocInfos.size())
-    LocInfo = DiagInfo->LocInfos[BufNum-1];
-
-  // If the inline asm had metadata associated with it, pull out a location
-  // cookie corresponding to which line the error occurred on.
-  unsigned LocCookie = 0;
-  if (LocInfo) {
-    unsigned ErrorLine = Diag.getLineNo()-1;
-    if (ErrorLine >= LocInfo->getNumOperands())
-      ErrorLine = 0;
-
-    if (LocInfo->getNumOperands() != 0)
-      if (const ConstantInt *CI =
-              mdconst::dyn_extract<ConstantInt>(LocInfo->getOperand(ErrorLine)))
-        LocCookie = CI->getZExtValue();
-  }
-
-  DiagInfo->DiagHandler(Diag, DiagInfo->DiagContext, LocCookie);
-}
-
 unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
                                             const MDNode *LocMDNode) const {
-  if (!DiagInfo) {
-    DiagInfo = std::make_unique<SrcMgrDiagInfo>();
-
-    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;
+  MCContext &Context = MMI->getContext();
+  Context.initInlineSourceManager();
+  SourceMgr &SrcMgr = *Context.getInlineSourceManager();
+  std::vector<const MDNode *> &LocInfos = Context.getLocInfos();
 
   std::unique_ptr<MemoryBuffer> Buffer;
   // The inline asm source manager will outlive AsmStr, so make a copy of the
@@ -98,8 +56,8 @@
 
   // Store LocMDNode in DiagInfo, using BufNum as an identifier.
   if (LocMDNode) {
-    DiagInfo->LocInfos.resize(BufNum);
-    DiagInfo->LocInfos[BufNum - 1] = LocMDNode;
+    LocInfos.resize(BufNum);
+    LocInfos[BufNum - 1] = LocMDNode;
   }
 
   return BufNum;
@@ -134,10 +92,11 @@
   }
 
   unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode);
-  DiagInfo->SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
+  SourceMgr &SrcMgr = *MMI->getContext().getInlineSourceManager();
+  SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
 
-  std::unique_ptr<MCAsmParser> Parser(createMCAsmParser(
-          DiagInfo->SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));
+  std::unique_ptr<MCAsmParser> Parser(
+      createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum));
 
   // Do not use assembler-level information for parsing inline assembly.
   OutStreamer->setUseAssemblerInfoForParsing(false);
@@ -162,12 +121,9 @@
 
   emitInlineAsmStart();
   // Don't implicitly switch to the text section before the asm.
-  int Res = Parser->Run(/*NoInitialTextSection*/ true,
-                        /*NoFinalize*/ true);
+  (void)Parser->Run(/*NoInitialTextSection*/ true,
+                    /*NoFinalize*/ true);
   emitInlineAsmEnd(STI, &TAP->getSTI());
-
-  if (Res && !DiagInfo->DiagHandler)
-    report_fatal_error("Error parsing inline asm\n");
 }
 
 static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
@@ -572,7 +528,7 @@
 
   if (!RestrRegs.empty()) {
     unsigned BufNum = addInlineAsmDiagBuffer(OS.str(), LocMD);
-    auto &SrcMgr = DiagInfo->SrcMgr;
+    auto &SrcMgr = *MMI->getContext().getInlineSourceManager();
     SMLoc Loc = SMLoc::getFromPointer(
         SrcMgr.getMemoryBuffer(BufNum)->getBuffer().begin());
 
Index: llvm/include/llvm/MC/MCContext.h
===================================================================
--- llvm/include/llvm/MC/MCContext.h
+++ llvm/include/llvm/MC/MCContext.h
@@ -35,6 +35,7 @@
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
+#include <functional>
 #include <map>
 #include <memory>
 #include <string>
@@ -59,6 +60,8 @@
   class MCSymbolELF;
   class MCSymbolWasm;
   class MCSymbolXCOFF;
+  class MDNode;
+  class SMDiagnostic;
   class SMLoc;
   class SourceMgr;
 
@@ -68,13 +71,19 @@
   class MCContext {
   public:
     using SymbolTable = StringMap<MCSymbol *, BumpPtrAllocator &>;
+    using DiagHandlerTy =
+        std::function<void(const SMDiagnostic &, bool, const SourceMgr &,
+                           std::vector<const MDNode *> &)>;
 
   private:
     /// The SourceMgr for this object, if any.
     const SourceMgr *SrcMgr;
 
     /// The SourceMgr for inline assembly, if any.
-    SourceMgr *InlineSrcMgr;
+    std::unique_ptr<SourceMgr> InlineSrcMgr;
+    std::vector<const MDNode *> LocInfos;
+
+    DiagHandlerTy DiagHandler;
 
     /// The MCAsmInfo for this target.
     const MCAsmInfo *MAI;
@@ -299,6 +308,9 @@
 
     bool HadError = false;
 
+    void reportCommon(std::function<void(SMDiagnostic &, const SourceMgr *)>,
+                      bool InlineAsm);
+
     MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
                                bool CanBeUnnamed);
     MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix,
@@ -363,7 +375,16 @@
 
     const SourceMgr *getSourceManager() const { return SrcMgr; }
 
-    void setInlineSourceManager(SourceMgr *SM) { InlineSrcMgr = SM; }
+    bool AsmParseMode = false;
+    void initInlineSourceManager();
+    SourceMgr *getInlineSourceManager() {
+      assert(InlineSrcMgr);
+      return InlineSrcMgr.get();
+    }
+    std::vector<const MDNode *> &getLocInfos() { return LocInfos; }
+    void setDiagnosticHandler(DiagHandlerTy DiagHandler) {
+      this->DiagHandler = DiagHandler;
+    }
 
     const MCAsmInfo *getAsmInfo() const { return MAI; }
 
@@ -748,13 +769,14 @@
     void deallocate(void *Ptr) {}
 
     bool hadError() { return HadError; }
-    void reportError(SMLoc L, const Twine &Msg);
-    void reportWarning(SMLoc L, const Twine &Msg);
+    void diagnose(const SMDiagnostic &SMD);
+    void reportError(SMLoc L, const Twine &Msg, bool InlineAsm = false);
+    void reportWarning(SMLoc L, const Twine &Msg, bool InlineAsm = false);
     // Unrecoverable error has occurred. Display the best diagnostic we can
     // and bail via exit(1). For now, most MC backend errors are unrecoverable.
     // FIXME: We should really do something about that.
-    LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L,
-                                                  const Twine &Msg);
+    LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg,
+                                                  bool InlineAsm = false);
 
     const MCAsmMacro *lookupMacro(StringRef Name) {
       StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name);
Index: llvm/include/llvm/IR/LLVMContext.h
===================================================================
--- llvm/include/llvm/IR/LLVMContext.h
+++ llvm/include/llvm/IR/LLVMContext.h
@@ -153,31 +153,10 @@
   void enableDebugTypeODRUniquing();
   void disableDebugTypeODRUniquing();
 
-  using InlineAsmDiagHandlerTy = void (*)(const SMDiagnostic&, void *Context,
-                                          unsigned LocCookie);
-
   /// Defines the type of a yield callback.
   /// \see LLVMContext::setYieldCallback.
   using YieldCallbackTy = void (*)(LLVMContext *Context, void *OpaqueHandle);
 
-  /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
-  /// when problems with inline asm are detected by the backend.  The first
-  /// argument is a function pointer and the second is a context pointer that
-  /// gets passed into the DiagHandler.
-  ///
-  /// LLVMContext doesn't take ownership or interpret either of these
-  /// pointers.
-  void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
-                                     void *DiagContext = nullptr);
-
-  /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
-  /// setInlineAsmDiagnosticHandler.
-  InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const;
-
-  /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
-  /// setInlineAsmDiagnosticHandler.
-  void *getInlineAsmDiagnosticContext() const;
-
   /// setDiagnosticHandlerCallBack - This method sets a handler call back
   /// that is invoked when the backend needs to report anything to the user.
   /// The first argument is a function pointer and the second is a context pointer
Index: llvm/include/llvm/IR/DiagnosticInfo.h
===================================================================
--- llvm/include/llvm/IR/DiagnosticInfo.h
+++ llvm/include/llvm/IR/DiagnosticInfo.h
@@ -78,6 +78,7 @@
   DK_MIRParser,
   DK_PGOProfile,
   DK_Unsupported,
+  DK_SrcMgr,
   DK_FirstPluginKind // Must be last value to work with
                      // getNextAvailablePluginDiagnosticKind
 };
@@ -1015,6 +1016,31 @@
   void print(DiagnosticPrinter &DP) const override;
 };
 
+class DiagnosticInfoSrcMgr : public DiagnosticInfo {
+  const SMDiagnostic &Diagnostic;
+  bool InlineAsmDiag;
+  unsigned LocCookie;
+
+public:
+  DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic,
+                       bool InlineAsmDiag = true, unsigned LocCookie = 0,
+                       DiagnosticSeverity Severity = DS_Error)
+      : DiagnosticInfo(DK_SrcMgr, Severity), Diagnostic(Diagnostic),
+        InlineAsmDiag(InlineAsmDiag), LocCookie(LocCookie) {}
+
+  bool isInlineAsmDiag() const { return InlineAsmDiag; }
+  const SMDiagnostic &getSMDiag() const { return Diagnostic; }
+  unsigned getLocCookie() const { return LocCookie; }
+
+  void print(DiagnosticPrinter &DP) const override {
+    llvm_unreachable("unimplemented");
+  }
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == DK_SrcMgr;
+  }
+};
+
 } // end namespace llvm
 
 #endif // LLVM_IR_DIAGNOSTICINFO_H
Index: llvm/include/llvm/CodeGen/AsmPrinter.h
===================================================================
--- llvm/include/llvm/CodeGen/AsmPrinter.h
+++ llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -185,14 +185,6 @@
   std::vector<HandlerInfo> Handlers;
   size_t NumUserHandlers = 0;
 
-public:
-  struct SrcMgrDiagInfo {
-    SourceMgr SrcMgr;
-    std::vector<const MDNode *> LocInfos;
-    LLVMContext::InlineAsmDiagHandlerTy DiagHandler;
-    void *DiagContext;
-  };
-
 private:
   /// If generated on the fly this own the instance.
   std::unique_ptr<MachineDominatorTree> OwnedMDT;
@@ -200,10 +192,6 @@
   /// If generated on the fly this own the instance.
   std::unique_ptr<MachineLoopInfo> OwnedMLI;
 
-  /// Structure for generating diagnostics for inline assembly. Only initialised
-  /// when necessary.
-  mutable std::unique_ptr<SrcMgrDiagInfo> DiagInfo;
-
   /// If the target supports dwarf debug info, this pointer is non-null.
   DwarfDebug *DD = nullptr;
 
Index: lldb/source/Expression/IRExecutionUnit.cpp
===================================================================
--- lldb/source/Expression/IRExecutionUnit.cpp
+++ lldb/source/Expression/IRExecutionUnit.cpp
@@ -9,6 +9,8 @@
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
 #include "llvm/ExecutionEngine/ObjectCache.h"
 #include "llvm/IR/Constants.h"
+#include "llvm/IR/DiagnosticHandler.h"
+#include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/SourceMgr.h"
@@ -200,16 +202,26 @@
   return ret;
 }
 
-static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic,
-                                 void *Context, unsigned LocCookie) {
-  Status *err = static_cast<Status *>(Context);
+namespace {
+struct IRExecDiagnosticHandler : public llvm::DiagnosticHandler {
+  Status *err;
+  IRExecDiagnosticHandler(Status *err) : err(err) {}
+  bool handleDiagnostics(const llvm::DiagnosticInfo &DI) override {
+    if (DI.getKind() == llvm::DK_SrcMgr) {
+      const auto &DISM = llvm::cast<llvm::DiagnosticInfoSrcMgr>(DI);
+      if (err && err->Success()) {
+        err->SetErrorToGenericError();
+        err->SetErrorStringWithFormat(
+            "Inline assembly error: %s",
+            DISM.getSMDiag().getMessage().str().c_str());
+      }
+      return true;
+    }
 
-  if (err && err->Success()) {
-    err->SetErrorToGenericError();
-    err->SetErrorStringWithFormat("Inline assembly error: %s",
-                                  diagnostic.getMessage().str().c_str());
+    return false;
   }
-}
+};
+} // namespace
 
 void IRExecutionUnit::ReportSymbolLookupError(ConstString name) {
   m_failed_lookups.push_back(name);
@@ -257,8 +269,8 @@
     LLDB_LOGF(log, "Module being sent to JIT: \n%s", s.c_str());
   }
 
-  m_module_up->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError,
-                                                          &error);
+  m_module_up->getContext().setDiagnosticHandler(
+      std::make_unique<IRExecDiagnosticHandler>(&error));
 
   llvm::EngineBuilder builder(std::move(m_module_up));
   llvm::Triple triple(m_module->getTargetTriple());
Index: clang/lib/CodeGen/CodeGenAction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenAction.cpp
+++ clang/lib/CodeGen/CodeGenAction.cpp
@@ -304,14 +304,7 @@
       if (!getModule())
         return;
 
-      // Install an inline asm handler so that diagnostics get printed through
-      // our diagnostics hooks.
       LLVMContext &Ctx = getModule()->getContext();
-      LLVMContext::InlineAsmDiagHandlerTy OldHandler =
-        Ctx.getInlineAsmDiagnosticHandler();
-      void *OldContext = Ctx.getInlineAsmDiagnosticContext();
-      Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);
-
       std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
           Ctx.getDiagnosticHandler();
       Ctx.setDiagnosticHandler(std::make_unique<ClangDiagnosticHandler>(
@@ -345,8 +338,6 @@
                         LangOpts, C.getTargetInfo().getDataLayout(),
                         getModule(), Action, std::move(AsmOutStream));
 
-      Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
-
       Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
 
       if (OptRecordFile)
@@ -380,12 +371,6 @@
       Gen->HandleVTable(RD);
     }
 
-    static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
-                                     unsigned LocCookie) {
-      SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
-      ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
-    }
-
     /// Get the best possible source location to represent a diagnostic that
     /// may have associated debug info.
     const FullSourceLoc
@@ -393,14 +378,12 @@
                                 bool &BadDebugInfo, StringRef &Filename,
                                 unsigned &Line, unsigned &Column) const;
 
-    void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
-                               SourceLocation LocCookie);
-
     void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
     /// Specialized handler for InlineAsm diagnostic.
     /// \return True if the diagnostic has been successfully reported, false
     /// otherwise.
     bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
+    bool InlineAsmDiagHandler(const llvm::DiagnosticInfoSrcMgr &D);
     /// Specialized handler for StackSize diagnostic.
     /// \return True if the diagnostic has been successfully reported, false
     /// otherwise.
@@ -459,24 +442,9 @@
   return FullSourceLoc(NewLoc, CSM);
 }
 
-
-/// InlineAsmDiagHandler2 - This function is invoked when the backend hits an
-/// error parsing inline asm.  The SMDiagnostic indicates the error relative to
-/// the temporary memory buffer that the inline asm parser has set up.
-void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D,
-                                            SourceLocation LocCookie) {
-  // There are a couple of different kinds of errors we could get here.  First,
-  // we re-format the SMDiagnostic in terms of a clang diagnostic.
-
-  // Strip "error: " off the start of the message string.
-  StringRef Message = D.getMessage();
-  if (Message.startswith("error: "))
-    Message = Message.substr(7);
-
-  // If the SMDiagnostic has an inline asm source location, translate it.
-  FullSourceLoc Loc;
-  if (D.getLoc() != SMLoc())
-    Loc = ConvertBackendLocation(D, Context->getSourceManager());
+bool BackendConsumer::InlineAsmDiagHandler(
+    const llvm::DiagnosticInfoSrcMgr &DI) {
+  const llvm::SMDiagnostic &D = DI.getSMDiag();
 
   unsigned DiagID;
   switch (D.getKind()) {
@@ -492,29 +460,56 @@
   case llvm::SourceMgr::DK_Remark:
     llvm_unreachable("remarks unexpected");
   }
+
+  // This is for the empty BackendConsumer that uses the clang diagnostic
+  // handler for IR input files.
+  if (!Context) {
+    D.print(nullptr, llvm::errs());
+    Diags.Report(DiagID).AddString("cannot compile inline asm");
+    return true;
+  }
+
+  // There are a couple of different kinds of errors we could get here.
+  // First, we re-format the SMDiagnostic in terms of a clang diagnostic.
+
+  // Strip "error: " off the start of the message string.
+  StringRef Message = D.getMessage();
+  if (Message.startswith("error: "))
+    Message = Message.substr(7);
+
+  // If the SMDiagnostic has an inline asm source location, translate it.
+  FullSourceLoc Loc;
+  if (D.getLoc() != SMLoc())
+    Loc = ConvertBackendLocation(D, Context->getSourceManager());
+
   // If this problem has clang-level source location information, report the
   // issue in the source with a note showing the instantiated
   // code.
-  if (LocCookie.isValid()) {
-    Diags.Report(LocCookie, DiagID).AddString(Message);
-
-    if (D.getLoc().isValid()) {
-      DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
-      // Convert the SMDiagnostic ranges into SourceRange and attach them
-      // to the diagnostic.
-      for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) {
-        unsigned Column = D.getColumnNo();
-        B << SourceRange(Loc.getLocWithOffset(Range.first - Column),
-                         Loc.getLocWithOffset(Range.second - Column));
+  if (DI.isInlineAsmDiag()) {
+    SourceLocation LocCookie =
+        SourceLocation::getFromRawEncoding(DI.getLocCookie());
+    if (LocCookie.isValid()) {
+      Diags.Report(LocCookie, DiagID).AddString(Message);
+
+      if (D.getLoc().isValid()) {
+        DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
+        // Convert the SMDiagnostic ranges into SourceRange and attach them
+        // to the diagnostic.
+        for (const std::pair<unsigned, unsigned> &Range : D.getRanges()) {
+          unsigned Column = D.getColumnNo();
+          B << SourceRange(Loc.getLocWithOffset(Range.first - Column),
+                           Loc.getLocWithOffset(Range.second - Column));
+        }
       }
+      return true;
     }
-    return;
   }
 
   // Otherwise, report the backend issue as occurring in the generated .s file.
   // If Loc is invalid, we still need to report the issue, it just gets no
   // location info.
   Diags.Report(Loc, DiagID).AddString(Message);
+  return true;
 }
 
 #define ComputeDiagID(Severity, GroupName, DiagID)                             \
@@ -791,6 +786,11 @@
       return;
     ComputeDiagID(Severity, inline_asm, DiagID);
     break;
+  case llvm::DK_SrcMgr:
+    if (InlineAsmDiagHandler(cast<DiagnosticInfoSrcMgr>(DI)))
+      return;
+    ComputeDiagID(Severity, inline_asm, DiagID);
+    break;
   case llvm::DK_StackSize:
     if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI)))
       return;
@@ -987,30 +987,6 @@
   return std::move(Result);
 }
 
-static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM,
-                                         void *Context,
-                                         unsigned LocCookie) {
-  SM.print(nullptr, llvm::errs());
-
-  auto Diags = static_cast<DiagnosticsEngine *>(Context);
-  unsigned DiagID;
-  switch (SM.getKind()) {
-  case llvm::SourceMgr::DK_Error:
-    DiagID = diag::err_fe_inline_asm;
-    break;
-  case llvm::SourceMgr::DK_Warning:
-    DiagID = diag::warn_fe_inline_asm;
-    break;
-  case llvm::SourceMgr::DK_Note:
-    DiagID = diag::note_fe_inline_asm;
-    break;
-  case llvm::SourceMgr::DK_Remark:
-    llvm_unreachable("remarks unexpected");
-  }
-
-  Diags->Report(DiagID).AddString("cannot compile inline asm");
-}
-
 std::unique_ptr<llvm::Module>
 CodeGenAction::loadModule(MemoryBufferRef MBRef) {
   CompilerInstance &CI = getCompilerInstance();
@@ -1113,7 +1089,6 @@
   EmbedBitcode(TheModule.get(), CodeGenOpts, *MainFile);
 
   LLVMContext &Ctx = TheModule->getContext();
-  Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, &Diagnostics);
 
   // Restore any diagnostic handler previously set before returning from this
   // function.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to