llvm.org GIT mirror llvm / 38686bd
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 Chris Lattner 10 years ago
3 changed file(s) with 50 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
1818
1919 class LLVMContextImpl;
2020 class StringRef;
21 class Instruction;
2122 template class SmallVectorImpl;
2223
2324 /// This is an important class for using LLVM in a threaded context. It
6768 /// setInlineAsmDiagnosticHandler.
6869 void *getInlineAsmDiagnosticContext() const;
6970
71
72 /// emitError - Emit an error message to the currently installed error handler
73 /// with optional location information. This function returns, so code should
74 /// be prepared to drop the erroneous construct on the floor and "not crash".
75 /// The generated code need not be correct. The error message will be
76 /// implicitly prefixed with "error: " and should not end with a ".".
77 void emitError(unsigned LocCookie, StringRef ErrorStr);
78 void emitError(const Instruction *I, StringRef ErrorStr);
79 void emitError(StringRef ErrorStr);
7080 };
7181
7282 /// getGlobalContext - Returns a global context. This is for LLVM clients that
294294 if (Error) {
295295 std::string msg;
296296 raw_string_ostream Msg(msg);
297 Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n";
298 MI->print(Msg);
299 report_fatal_error(Msg.str());
297 Msg << "invalid operand in inline asm: '" << AsmStr << "'";
298 MMI->getModule()->getContext().emitError(LocCookie, Msg.str());
300299 }
301300 }
302301 break;
1616 #include "llvm/Constants.h"
1717 #include "llvm/Instruction.h"
1818 #include "llvm/Support/ManagedStatic.h"
19 #include "llvm/Support/SourceMgr.h"
1920 #include "LLVMContextImpl.h"
2021 using namespace llvm;
2122
3132 assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
3233 }
3334 LLVMContext::~LLVMContext() { delete pImpl; }
35
36 //===----------------------------------------------------------------------===//
37 // Recoverable Backend Errors
38 //===----------------------------------------------------------------------===//
3439
3540 void LLVMContext::setInlineAsmDiagnosticHandler(void *DiagHandler,
3641 void *DiagContext) {
4954 void *LLVMContext::getInlineAsmDiagnosticContext() const {
5055 return pImpl->InlineAsmDiagContext;
5156 }
57
58 void LLVMContext::emitError(StringRef ErrorStr) {
59 emitError(0U, ErrorStr);
60 }
61
62 void LLVMContext::emitError(const Instruction *I, StringRef ErrorStr) {
63 unsigned LocCookie = 0;
64 if (const MDNode *SrcLoc = I->getMetadata("srcloc")) {
65 if (SrcLoc->getNumOperands() != 0)
66 if (const ConstantInt *CI = dyn_cast(SrcLoc->getOperand(0)))
67 LocCookie = CI->getZExtValue();
68 }
69 return emitError(LocCookie, ErrorStr);
70 }
71
72 void LLVMContext::emitError(unsigned LocCookie, StringRef ErrorStr) {
73 // If there is no error handler installed, just print the error and exit.
74 if (pImpl->InlineAsmDiagHandler == 0) {
75 errs() << "error: " << ErrorStr << "\n";
76 exit(1);
77 }
78
79 // If we do have an error handler, we can report the error and keep going.
80 SMDiagnostic Diag("", "error: " + ErrorStr.str());
81
82 ((SourceMgr::DiagHandlerTy)(intptr_t)pImpl->InlineAsmDiagHandler)
83 (Diag, pImpl->InlineAsmDiagContext, LocCookie);
84
85 }
86
87 //===----------------------------------------------------------------------===//
88 // Metadata Kind Uniquing
89 //===----------------------------------------------------------------------===//
5290
5391 #ifndef NDEBUG
5492 /// isValidName - Return true if Name is a valid custom metadata handler name.