Add simple support for keeping MCFixup source information.

Can be used to issue more user friendly diagnostics for faulty
relocation constructs and such.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149092 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2012-01-26 23:20:11 +00:00
parent 93cd59aea8
commit 82f4ce5081
4 changed files with 38 additions and 2 deletions

View File

@ -15,6 +15,8 @@
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <vector> // FIXME: Shouldn't be needed. #include <vector> // FIXME: Shouldn't be needed.
@ -319,6 +321,11 @@ namespace llvm {
} }
void Deallocate(void *Ptr) { 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 } // end namespace llvm

View File

@ -11,6 +11,7 @@
#define LLVM_MC_MCFIXUP_H #define LLVM_MC_MCFIXUP_H
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
#include <cassert> #include <cassert>
namespace llvm { namespace llvm {
@ -69,14 +70,17 @@ class MCFixup {
/// determine how the operand value should be encoded into the instruction. /// determine how the operand value should be encoded into the instruction.
unsigned Kind; unsigned Kind;
/// The source location which gave rise to the fixup, if any.
SMLoc Loc;
public: public:
static MCFixup Create(uint32_t Offset, const MCExpr *Value, static MCFixup Create(uint32_t Offset, const MCExpr *Value,
MCFixupKind Kind) { MCFixupKind Kind, SMLoc Loc = SMLoc()) {
assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!"); assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
MCFixup FI; MCFixup FI;
FI.Value = Value; FI.Value = Value;
FI.Offset = Offset; FI.Offset = Offset;
FI.Kind = unsigned(Kind); FI.Kind = unsigned(Kind);
FI.Loc = Loc;
return FI; return FI;
} }
@ -98,6 +102,8 @@ public:
case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8; case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
} }
} }
SMLoc getLoc() const { return Loc; }
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h" #include "llvm/Support/DataTypes.h"
#include "llvm/Support/SMLoc.h"
namespace llvm { namespace llvm {
class raw_ostream; class raw_ostream;
@ -148,14 +149,17 @@ template <> struct isPodLike<MCOperand> { static const bool value = true; };
/// instruction. /// instruction.
class MCInst { class MCInst {
unsigned Opcode; unsigned Opcode;
SMLoc Loc;
SmallVector<MCOperand, 8> Operands; SmallVector<MCOperand, 8> Operands;
public: public:
MCInst() : Opcode(0) {} MCInst() : Opcode(0) {}
void setOpcode(unsigned Op) { Opcode = Op; } void setOpcode(unsigned Op) { Opcode = Op; }
unsigned getOpcode() const { return Opcode; } 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]; } const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
MCOperand &getOperand(unsigned i) { return Operands[i]; } MCOperand &getOperand(unsigned i) { return Operands[i]; }
unsigned getNumOperands() const { return Operands.size(); } unsigned getNumOperands() const { return Operands.size(); }

View File

@ -20,6 +20,9 @@
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h" #include "llvm/ADT/Twine.h"
#include "llvm/Support/ELF.h" #include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Signals.h"
using namespace llvm; using namespace llvm;
typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy; typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy;
@ -321,3 +324,19 @@ bool MCContext::isValidDwarfFileNumber(unsigned FileNumber) {
return MCDwarfFiles[FileNumber] != 0; 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);
}