1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[Diagnose] Unify MCContext and LLVMContext diagnosing

The situation with inline asm/MC error reporting is kind of messy at the
moment. The errors from MC layout are not reliably propagated and users
have to specify an inlineasm handler separately to get inlineasm
diagnose. The latter issue is not a correctness issue but could be improved.

* Kill LLVMContext inlineasm diagnose handler and migrate it to use
  DiagnoseInfo/DiagnoseHandler.
* Introduce `DiagnoseInfoSrcMgr` to diagnose SourceMgr backed errors. This
  covers use cases like inlineasm, MC, and any clients using SourceMgr.
* Move AsmPrinter::SrcMgrDiagInfo and its instance to MCContext. The next step
  is to combine MCContext::SrcMgr and MCContext::InlineSrcMgr because in all
  use cases, only one of them is used.
* If LLVMContext is available, let MCContext uses LLVMContext's diagnose
  handler; if LLVMContext is not available, MCContext uses its own default
  diagnose handler which just prints SMDiagnostic.
* Change a few clients(Clang, llc, lldb) to use the new way of reporting.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D97449
This commit is contained in:
Yuanfang Chen 2021-02-23 09:47:15 -08:00
parent a7362a2fcb
commit afa87767f4
15 changed files with 219 additions and 168 deletions

View File

@ -185,14 +185,6 @@ protected:
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 @@ private:
/// 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;

View File

@ -78,6 +78,7 @@ enum DiagnosticKind {
DK_MIRParser,
DK_PGOProfile,
DK_Unsupported,
DK_SrcMgr,
DK_FirstPluginKind // Must be last value to work with
// getNextAvailablePluginDiagnosticKind
};
@ -916,6 +917,7 @@ private:
};
/// Diagnostic information for machine IR parser.
// FIXME: Remove this, use DiagnosticInfoSrcMgr instead.
class DiagnosticInfoMIRParser : public DiagnosticInfo {
const SMDiagnostic &Diagnostic;
@ -1015,6 +1017,49 @@ public:
void print(DiagnosticPrinter &DP) const override;
};
static DiagnosticSeverity getDiagnosticSeverity(SourceMgr::DiagKind DK) {
switch (DK) {
case llvm::SourceMgr::DK_Error:
return DS_Error;
break;
case llvm::SourceMgr::DK_Warning:
return DS_Warning;
break;
case llvm::SourceMgr::DK_Note:
return DS_Note;
break;
case llvm::SourceMgr::DK_Remark:
return DS_Remark;
break;
}
llvm_unreachable("unknown SourceMgr::DiagKind");
}
/// Diagnostic information for SMDiagnostic reporting.
class DiagnosticInfoSrcMgr : public DiagnosticInfo {
const SMDiagnostic &Diagnostic;
// For inlineasm !srcloc translation.
bool InlineAsmDiag;
unsigned LocCookie;
public:
DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic,
bool InlineAsmDiag = true, unsigned LocCookie = 0)
: DiagnosticInfo(DK_SrcMgr, getDiagnosticSeverity(Diagnostic.getKind())),
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;
static bool classof(const DiagnosticInfo *DI) {
return DI->getKind() == DK_SrcMgr;
}
};
} // end namespace llvm
#endif // LLVM_IR_DIAGNOSTICINFO_H

View File

@ -153,31 +153,10 @@ public:
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

View File

@ -35,6 +35,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <string>
@ -59,6 +60,8 @@ namespace llvm {
class MCSymbolELF;
class MCSymbolWasm;
class MCSymbolXCOFF;
class MDNode;
class SMDiagnostic;
class SMLoc;
class SourceMgr;
@ -68,13 +71,19 @@ namespace llvm {
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 @@ namespace llvm {
bool HadError = false;
void reportCommon(SMLoc Loc,
std::function<void(SMDiagnostic &, const SourceMgr *)>);
MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
bool CanBeUnnamed);
MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix,
@ -363,7 +375,15 @@ namespace llvm {
const SourceMgr *getSourceManager() const { return SrcMgr; }
void setInlineSourceManager(SourceMgr *SM) { InlineSrcMgr = SM; }
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 +768,13 @@ namespace llvm {
void deallocate(void *Ptr) {}
bool hadError() { return HadError; }
void diagnose(const SMDiagnostic &SMD);
void reportError(SMLoc L, const Twine &Msg);
void reportWarning(SMLoc L, const Twine &Msg);
// 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);
const MCAsmMacro *lookupMacro(StringRef Name) {
StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name);

View File

@ -39,54 +39,12 @@ using namespace llvm;
#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 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
// 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 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
}
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 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
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 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
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());

View File

@ -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 @@ INITIALIZE_PASS(MachineModuleInfoWrapperPass, "machinemoduleinfo",
"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;
}

View File

@ -330,6 +330,10 @@ void DiagnosticInfoMIRParser::print(DiagnosticPrinter &DP) const {
DP << Diagnostic;
}
void DiagnosticInfoSrcMgr::print(DiagnosticPrinter &DP) const {
DP << Diagnostic;
}
DiagnosticInfoOptimizationFailure::DiagnosticInfoOptimizationFailure(
const char *PassName, StringRef RemarkName, const DiagnosticLocation &Loc,
const Value *CodeRegion)

View File

@ -111,26 +111,6 @@ void LLVMContext::removeModule(Module *M) {
// 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) {

View File

@ -1314,9 +1314,6 @@ public:
/// 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.

View File

@ -57,11 +57,16 @@ AsSecureLogFileName("as-secure-log-file-name",
"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,21 @@ MCContext::~MCContext() {
// 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;
// Call the destructors so the fragments are freed
COFFAllocator.DestroyAll();
ELFAllocator.DestroyAll();
@ -835,32 +850,67 @@ CodeViewContext &MCContext::getCVContext() {
// Error Reporting
//===----------------------------------------------------------------------===//
void MCContext::diagnose(const SMDiagnostic &SMD) {
assert(DiagHandler && "MCContext::DiagHandler is not set");
bool UseInlineSrcMgr = false;
const SourceMgr *SMP = nullptr;
if (SrcMgr) {
SMP = SrcMgr;
} else if (InlineSrcMgr) {
SMP = InlineSrcMgr.get();
UseInlineSrcMgr = true;
} else
llvm_unreachable("Either SourceMgr should be available");
DiagHandler(SMD, UseInlineSrcMgr, *SMP, LocInfos);
}
void MCContext::reportCommon(
SMLoc Loc,
std::function<void(SMDiagnostic &, const SourceMgr *)> GetMessage) {
// * MCContext::SrcMgr is null when the MC layer emits machine code for input
// other than assembly file, say, for .c/.cpp/.ll/.bc.
// * MCContext::InlineSrcMgr is null when the inline asm is not used.
// * A default SourceMgr is needed for diagnosing when both MCContext::SrcMgr
// and MCContext::InlineSrcMgr are null.
SourceMgr SM;
const SourceMgr *SMP = &SM;
bool UseInlineSrcMgr = false;
// FIXME: Simplify these by combining InlineSrcMgr & SrcMgr.
// For MC-only execution, only SrcMgr is used;
// For non MC-only execution, InlineSrcMgr is only ctor'd if there is
// inline asm in the IR.
if (Loc.isValid()) {
if (SrcMgr) {
SMP = SrcMgr;
} else if (InlineSrcMgr) {
SMP = InlineSrcMgr.get();
UseInlineSrcMgr = true;
} else
llvm_unreachable("Either SourceMgr should be available");
}
SMDiagnostic D;
GetMessage(D, SMP);
DiagHandler(D, UseInlineSrcMgr, *SMP, LocInfos);
}
void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
HadError = 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);
reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {
D = SMP->GetMessage(Loc, SourceMgr::DK_Error, Msg);
});
}
void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) {
if (TargetOptions && TargetOptions->MCNoWarn)
return;
if (TargetOptions && TargetOptions->MCFatalWarnings)
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);
} else {
reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {
D = SMP->GetMessage(Loc, SourceMgr::DK_Warning, Msg);
});
}
}

View File

@ -2348,7 +2348,7 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo) {
/// 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 +2369,8 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
// 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 +2389,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
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

View File

@ -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

View File

@ -1,7 +1,7 @@
; 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 -filetype=null < %s 2>&1 | FileCheck %s
; RUN: not llc -march=amdgcn -mcpu=tonga -filetype=null < %s 2>&1 | FileCheck %s
; CHECK: lds: unsupported initializer for address space
; CHECK: error: lds: unsupported initializer for address space
@lds = addrspace(3) global [256 x i32] zeroinitializer

View File

@ -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

View File

@ -290,6 +290,22 @@ struct LLCDiagnosticHandler : public DiagnosticHandler {
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 @@ struct LLCDiagnosticHandler : public DiagnosticHandler {
}
};
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 @@ int main(int argc, char **argv) {
bool HasError = false;
Context.setDiagnosticHandler(
std::make_unique<LLCDiagnosticHandler>(&HasError));
Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError);
Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,