diff options
author | Chris Lattner <sabre@nondot.org> | 2010-04-07 23:40:44 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-04-07 23:40:44 +0000 |
commit | 38686bdffdebc09aa6fe6b8b54b34ac32c753f59 (patch) | |
tree | 86a65f6c9f9b63270378b4c824fe40a3b00c57ef /lib/VMCore | |
parent | a5ced590c95035793c2ae19bf70d6a0ed2c822a6 (diff) | |
download | external_llvm-38686bdffdebc09aa6fe6b8b54b34ac32c753f59.zip external_llvm-38686bdffdebc09aa6fe6b8b54b34ac32c753f59.tar.gz external_llvm-38686bdffdebc09aa6fe6b8b54b34ac32c753f59.tar.bz2 |
introduce a new recoverable error handling API to LLVMContext
and use it in one place in inline asm handling stuff. Before
we'd generate this for an invalid modifier letter:
$ clang asm.c -c -o t.o
fatal error: error in backend: Invalid operand found in inline asm: 'abc incl ${0:Z}'
INLINEASM <es:abc incl ${0:Z}>, 10, %EAX<def>, 2147483657, %EAX, 14, %EFLAGS<earlyclobber,def,dead>, <!-1>
Now we generate this:
$ clang asm.c -c -o t.o
error: invalid operand in inline asm: 'incl ${0:Z}'
asm.c:3:12: note: generated from here
__asm__ ("incl %Z0" : "+r" (X));
^
1 error generated.
This is much better but still admittedly not great ("why" is the operand
invalid??), codegen should try harder with its diagnostics :)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100723 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/LLVMContext.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 3244f28..4d61363 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -17,6 +17,7 @@ #include "llvm/Constants.h" #include "llvm/Instruction.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/SourceMgr.h" #include "LLVMContextImpl.h" using namespace llvm; @@ -33,6 +34,10 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { } LLVMContext::~LLVMContext() { delete pImpl; } +//===----------------------------------------------------------------------===// +// Recoverable Backend Errors +//===----------------------------------------------------------------------===// + void LLVMContext::setInlineAsmDiagnosticHandler(void *DiagHandler, void *DiagContext) { pImpl->InlineAsmDiagHandler = DiagHandler; @@ -51,6 +56,39 @@ void *LLVMContext::getInlineAsmDiagnosticContext() const { return pImpl->InlineAsmDiagContext; } +void LLVMContext::emitError(StringRef ErrorStr) { + emitError(0U, ErrorStr); +} + +void LLVMContext::emitError(const Instruction *I, StringRef ErrorStr) { + unsigned LocCookie = 0; + if (const MDNode *SrcLoc = I->getMetadata("srcloc")) { + if (SrcLoc->getNumOperands() != 0) + if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0))) + LocCookie = CI->getZExtValue(); + } + return emitError(LocCookie, ErrorStr); +} + +void LLVMContext::emitError(unsigned LocCookie, StringRef ErrorStr) { + // If there is no error handler installed, just print the error and exit. + if (pImpl->InlineAsmDiagHandler == 0) { + errs() << "error: " << ErrorStr << "\n"; + exit(1); + } + + // If we do have an error handler, we can report the error and keep going. + SMDiagnostic Diag("", "error: " + ErrorStr.str()); + + ((SourceMgr::DiagHandlerTy)(intptr_t)pImpl->InlineAsmDiagHandler) + (Diag, pImpl->InlineAsmDiagContext, LocCookie); + +} + +//===----------------------------------------------------------------------===// +// Metadata Kind Uniquing +//===----------------------------------------------------------------------===// + #ifndef NDEBUG /// isValidName - Return true if Name is a valid custom metadata handler name. static bool isValidName(StringRef MDName) { |