#ifndef LLVM_MC_MCDWARF_H
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineLocation.h" // FIXME
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Dwarf.h"
#include <vector>
namespace llvm {
class TargetAsmInfo;
class MachineMove;
class MCContext;
class MCExpr;
class MCSection;
class MCSectionData;
class MCStreamer;
class MCSymbol;
class MCObjectStreamer;
class raw_ostream;
class MCDwarfFile {
StringRef Name;
unsigned DirIndex;
private: friend class MCContext;
MCDwarfFile(StringRef name, unsigned dirIndex)
: Name(name), DirIndex(dirIndex) {}
MCDwarfFile(const MCDwarfFile&); void operator=(const MCDwarfFile&); public:
StringRef getName() const { return Name; }
unsigned getDirIndex() const { return DirIndex; }
void print(raw_ostream &OS) const;
void dump() const;
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCDwarfFile &DwarfFile){
DwarfFile.print(OS);
return OS;
}
class MCDwarfLoc {
unsigned FileNum;
unsigned Line;
unsigned Column;
unsigned Flags;
unsigned Isa;
unsigned Discriminator;
#define DWARF2_LINE_DEFAULT_IS_STMT 1
#define DWARF2_FLAG_IS_STMT (1 << 0)
#define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
#define DWARF2_FLAG_PROLOGUE_END (1 << 2)
#define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
private: friend class MCContext;
friend class MCLineEntry;
MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
unsigned isa, unsigned discriminator)
: FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
Discriminator(discriminator) {}
public:
unsigned getFileNum() const { return FileNum; }
unsigned getLine() const { return Line; }
unsigned getColumn() const { return Column; }
unsigned getFlags() const { return Flags; }
unsigned getIsa() const { return Isa; }
unsigned getDiscriminator() const { return Discriminator; }
void setFileNum(unsigned fileNum) { FileNum = fileNum; }
void setLine(unsigned line) { Line = line; }
void setColumn(unsigned column) { Column = column; }
void setFlags(unsigned flags) { Flags = flags; }
void setIsa(unsigned isa) { Isa = isa; }
void setDiscriminator(unsigned discriminator) {
Discriminator = discriminator;
}
};
class MCLineEntry : public MCDwarfLoc {
MCSymbol *Label;
private:
public:
MCLineEntry(MCSymbol *label, const MCDwarfLoc loc) : MCDwarfLoc(loc),
Label(label) {}
MCSymbol *getLabel() const { return Label; }
static void Make(MCStreamer *MCOS, const MCSection *Section);
};
class MCLineSection {
private:
MCLineSection(const MCLineSection&); void operator=(const MCLineSection&);
public:
MCLineSection() {}
void addLineEntry(const MCLineEntry &LineEntry) {
MCLineEntries.push_back(LineEntry);
}
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
typedef MCLineEntryCollection::const_iterator const_iterator;
private:
MCLineEntryCollection MCLineEntries;
public:
const MCLineEntryCollection *getMCLineEntries() const {
return &MCLineEntries;
}
};
class MCDwarfFileTable {
public:
static void Emit(MCStreamer *MCOS);
};
class MCDwarfLineAddr {
public:
static void Encode(int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS);
static void Emit(MCStreamer *MCOS,
int64_t LineDelta,uint64_t AddrDelta);
static void Write(MCObjectWriter *OW,
int64_t LineDelta, uint64_t AddrDelta);
};
class MCCFIInstruction {
public:
enum OpType { SameValue, Remember, Restore, Move, RelMove };
private:
OpType Operation;
MCSymbol *Label;
MachineLocation Destination;
MachineLocation Source;
public:
MCCFIInstruction(OpType Op, MCSymbol *L)
: Operation(Op), Label(L) {
assert(Op == Remember || Op == Restore);
}
MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
: Operation(Op), Label(L), Destination(Register) {
assert(Op == SameValue);
}
MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
const MachineLocation &S)
: Operation(Move), Label(L), Destination(D), Source(S) {
}
MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
const MachineLocation &S)
: Operation(Op), Label(L), Destination(D), Source(S) {
assert(Op == RelMove);
}
OpType getOperation() const { return Operation; }
MCSymbol *getLabel() const { return Label; }
const MachineLocation &getDestination() const { return Destination; }
const MachineLocation &getSource() const { return Source; }
};
struct MCDwarfFrameInfo {
MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
Function(0), Instructions(), PersonalityEncoding(),
LsdaEncoding(0) {}
MCSymbol *Begin;
MCSymbol *End;
const MCSymbol *Personality;
const MCSymbol *Lsda;
const MCSymbol *Function;
std::vector<MCCFIInstruction> Instructions;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
};
class MCDwarfFrameEmitter {
public:
static void Emit(MCStreamer &streamer, bool usingCFI,
bool isEH);
static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
};
}
#endif