diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index a1da8c5381b..8b4e296bac1 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -15,6 +15,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/SMLoc.h" #include "llvm/Support/raw_ostream.h" #include // FIXME: Shouldn't be needed. @@ -319,6 +321,11 @@ namespace llvm { } void Deallocate(void *Ptr) { } + + // Unrecoverable error has occured. 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 FatalError(SMLoc L, const Twine &Msg); }; } // end namespace llvm diff --git a/include/llvm/MC/MCFixup.h b/include/llvm/MC/MCFixup.h index 4aa361b2df9..aaf5fe1a46a 100644 --- a/include/llvm/MC/MCFixup.h +++ b/include/llvm/MC/MCFixup.h @@ -11,6 +11,7 @@ #define LLVM_MC_MCFIXUP_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/SMLoc.h" #include namespace llvm { @@ -69,14 +70,17 @@ class MCFixup { /// determine how the operand value should be encoded into the instruction. unsigned Kind; + /// The source location which gave rise to the fixup, if any. + SMLoc Loc; public: static MCFixup Create(uint32_t Offset, const MCExpr *Value, - MCFixupKind Kind) { + MCFixupKind Kind, SMLoc Loc = SMLoc()) { assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!"); MCFixup FI; FI.Value = Value; FI.Offset = Offset; FI.Kind = unsigned(Kind); + FI.Loc = Loc; return FI; } @@ -98,6 +102,8 @@ public: case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8; } } + + SMLoc getLoc() const { return Loc; } }; } // End llvm namespace diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index a2ade57fa5f..397a37d3ce4 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/SMLoc.h" namespace llvm { class raw_ostream; @@ -148,14 +149,17 @@ template <> struct isPodLike { static const bool value = true; }; /// instruction. class MCInst { unsigned Opcode; + SMLoc Loc; SmallVector Operands; public: MCInst() : Opcode(0) {} void setOpcode(unsigned Op) { Opcode = Op; } - unsigned getOpcode() const { return Opcode; } + void setLoc(SMLoc loc) { Loc = loc; } + SMLoc getLoc() const { return Loc; } + const MCOperand &getOperand(unsigned i) const { return Operands[i]; } MCOperand &getOperand(unsigned i) { return Operands[i]; } unsigned getNumOperands() const { return Operands.size(); } diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index e22a5ab1d9f..d3c4fb1d7ca 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -20,6 +20,9 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/Signals.h" using namespace llvm; typedef StringMap MachOUniqueMapTy; @@ -321,3 +324,19 @@ bool MCContext::isValidDwarfFileNumber(unsigned FileNumber) { return MCDwarfFiles[FileNumber] != 0; } + +void MCContext::FatalError(SMLoc Loc, const Twine &Msg) { + // If we have a source manager and a location, use it. Otherwise just + // use the generic report_fatal_error(). + if (!SrcMgr || Loc == SMLoc()) + report_fatal_error(Msg); + + // Use the source manager to print the message. + SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); + + // 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 + // files registered with RemoveFileOnSignal. + sys::RunInterruptHandlers(); + exit(1); +}