#ifndef LLVM_MC_MCCONTEXT_H
#define LLVM_MC_MCCONTEXT_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <tuple>
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
class MCAsmInfo;
class MCExpr;
class MCSection;
class MCSymbol;
class MCSymbolELF;
class MCLabel;
struct MCDwarfFile;
class MCDwarfLoc;
class MCObjectFileInfo;
class MCRegisterInfo;
class MCLineSection;
class SMLoc;
class MCSectionMachO;
class MCSectionELF;
class MCSectionCOFF;
class MCContext {
MCContext(const MCContext &) = delete;
MCContext &operator=(const MCContext &) = delete;
public:
typedef StringMap<MCSymbol *, BumpPtrAllocator &> SymbolTable;
private:
const SourceMgr *SrcMgr;
const MCAsmInfo *MAI;
const MCRegisterInfo *MRI;
const MCObjectFileInfo *MOFI;
BumpPtrAllocator Allocator;
SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator;
SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
SymbolTable Symbols;
DenseMap<const MCSectionELF *, MCSymbolELF *> SectionSymbols;
DenseMap<std::pair<unsigned, unsigned>, MCSymbol *> LocalSymbols;
StringMap<bool, BumpPtrAllocator &> UsedNames;
StringMap<unsigned> NextID;
DenseMap<unsigned, MCLabel *> Instances;
unsigned NextInstance(unsigned LocalLabelVal);
unsigned GetInstance(unsigned LocalLabelVal);
char *SecureLogFile;
std::unique_ptr<raw_fd_ostream> SecureLog;
bool SecureLogUsed;
SmallString<128> CompilationDir;
std::string MainFileName;
std::map<unsigned, MCDwarfLineTable> MCDwarfLineTablesCUMap;
MCDwarfLoc CurrentDwarfLoc;
bool DwarfLocSeen;
bool GenDwarfForAssembly;
unsigned GenDwarfFileNumber;
SetVector<MCSection *> SectionsForRanges;
std::vector<MCGenDwarfLabelEntry> MCGenDwarfLabelEntries;
StringRef DwarfDebugFlags;
StringRef DwarfDebugProducer;
uint16_t DwarfVersion;
bool AllowTemporaryLabels;
bool UseNamesOnTempLabels = true;
unsigned DwarfCompileUnitID;
struct ELFSectionKey {
std::string SectionName;
StringRef GroupName;
unsigned UniqueID;
ELFSectionKey(StringRef SectionName, StringRef GroupName,
unsigned UniqueID)
: SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
}
bool operator<(const ELFSectionKey &Other) const {
if (SectionName != Other.SectionName)
return SectionName < Other.SectionName;
if (GroupName != Other.GroupName)
return GroupName < Other.GroupName;
return UniqueID < Other.UniqueID;
}
};
struct COFFSectionKey {
std::string SectionName;
StringRef GroupName;
int SelectionKey;
COFFSectionKey(StringRef SectionName, StringRef GroupName,
int SelectionKey)
: SectionName(SectionName), GroupName(GroupName),
SelectionKey(SelectionKey) {}
bool operator<(const COFFSectionKey &Other) const {
if (SectionName != Other.SectionName)
return SectionName < Other.SectionName;
if (GroupName != Other.GroupName)
return GroupName < Other.GroupName;
return SelectionKey < Other.SelectionKey;
}
};
StringMap<MCSectionMachO *> MachOUniquingMap;
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
StringMap<bool> ELFRelSecNames;
SpecificBumpPtrAllocator<MCSubtargetInfo> MCSubtargetAllocator;
bool AutoReset;
bool HadError;
MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name,
bool CanBeUnnamed);
MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix,
bool IsTemporary);
MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance);
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
const MCObjectFileInfo *MOFI,
const SourceMgr *Mgr = nullptr, bool DoAutoReset = true);
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
const MCAsmInfo *getAsmInfo() const { return MAI; }
const MCRegisterInfo *getRegisterInfo() const { return MRI; }
const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; }
void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; }
void reset();
MCSymbol *createLinkerPrivateTempSymbol();
MCSymbol *createTempSymbol(bool CanBeUnnamed = true);
MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix,
bool CanBeUnnamed = true);
MCSymbol *createDirectionalLocalSymbol(unsigned LocalLabelVal);
MCSymbol *getDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before);
MCSymbol *getOrCreateSymbol(const Twine &Name);
MCSymbolELF *getOrCreateSectionSymbol(const MCSectionELF &Section);
MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
MCSymbol *getOrCreateParentFrameOffsetSymbol(StringRef FuncName);
MCSymbol *getOrCreateLSDASymbol(StringRef FuncName);
MCSymbol *lookupSymbol(const Twine &Name) const;
const SymbolTable &getSymbols() const { return Symbols; }
MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
unsigned TypeAndAttributes,
unsigned Reserved2, SectionKind K,
const char *BeginSymName = nullptr);
MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
unsigned TypeAndAttributes, SectionKind K,
const char *BeginSymName = nullptr) {
return getMachOSection(Segment, Section, TypeAndAttributes, 0, K,
BeginSymName);
}
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags) {
return getELFSection(Section, Type, Flags, nullptr);
}
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, const char *BeginSymName) {
return getELFSection(Section, Type, Flags, 0, "", BeginSymName);
}
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
StringRef Group) {
return getELFSection(Section, Type, Flags, EntrySize, Group, nullptr);
}
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
StringRef Group, const char *BeginSymName) {
return getELFSection(Section, Type, Flags, EntrySize, Group, ~0,
BeginSymName);
}
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
StringRef Group, unsigned UniqueID) {
return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID,
nullptr);
}
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
StringRef Group, unsigned UniqueID,
const char *BeginSymName);
MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group, unsigned UniqueID,
const char *BeginSymName,
const MCSectionELF *Associated);
MCSectionELF *createELFRelSection(StringRef Name, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group,
const MCSectionELF *Associated);
void renameELFSection(MCSectionELF *Section, StringRef Name);
MCSectionELF *createELFGroupSection(const MCSymbolELF *Group);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
int Selection,
const char *BeginSymName = nullptr);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind,
const char *BeginSymName = nullptr);
MCSectionCOFF *getCOFFSection(StringRef Section);
MCSectionCOFF *getAssociativeCOFFSection(MCSectionCOFF *Sec,
const MCSymbol *KeySym);
MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
StringRef getCompilationDir() const { return CompilationDir; }
void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
const std::string &getMainFileName() const { return MainFileName; }
void setMainFileName(StringRef S) { MainFileName = S; }
unsigned getDwarfFile(StringRef Directory, StringRef FileName,
unsigned FileNumber, unsigned CUID);
bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
const std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const {
return MCDwarfLineTablesCUMap;
}
MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) {
return MCDwarfLineTablesCUMap[CUID];
}
const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const {
auto I = MCDwarfLineTablesCUMap.find(CUID);
assert(I != MCDwarfLineTablesCUMap.end());
return I->second;
}
const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) {
return getMCDwarfLineTable(CUID).getMCDwarfFiles();
}
const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) {
return getMCDwarfLineTable(CUID).getMCDwarfDirs();
}
bool hasMCLineSections() const {
for (const auto &Table : MCDwarfLineTablesCUMap)
if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel())
return true;
return false;
}
unsigned getDwarfCompileUnitID() { return DwarfCompileUnitID; }
void setDwarfCompileUnitID(unsigned CUIndex) {
DwarfCompileUnitID = CUIndex;
}
void setMCLineTableCompilationDir(unsigned CUID, StringRef CompilationDir) {
getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
}
void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
unsigned Flags, unsigned Isa,
unsigned Discriminator) {
CurrentDwarfLoc.setFileNum(FileNum);
CurrentDwarfLoc.setLine(Line);
CurrentDwarfLoc.setColumn(Column);
CurrentDwarfLoc.setFlags(Flags);
CurrentDwarfLoc.setIsa(Isa);
CurrentDwarfLoc.setDiscriminator(Discriminator);
DwarfLocSeen = true;
}
void clearDwarfLocSeen() { DwarfLocSeen = false; }
bool getDwarfLocSeen() { return DwarfLocSeen; }
const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; }
bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
void setGenDwarfFileNumber(unsigned FileNumber) {
GenDwarfFileNumber = FileNumber;
}
const SetVector<MCSection *> &getGenDwarfSectionSyms() {
return SectionsForRanges;
}
bool addGenDwarfSection(MCSection *Sec) {
return SectionsForRanges.insert(Sec);
}
void finalizeDwarfSections(MCStreamer &MCOS);
const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
return MCGenDwarfLabelEntries;
}
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E) {
MCGenDwarfLabelEntries.push_back(E);
}
void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
void setDwarfVersion(uint16_t v) { DwarfVersion = v; }
uint16_t getDwarfVersion() const { return DwarfVersion; }
char *getSecureLogFile() { return SecureLogFile; }
raw_fd_ostream *getSecureLog() { return SecureLog.get(); }
bool getSecureLogUsed() { return SecureLogUsed; }
void setSecureLog(std::unique_ptr<raw_fd_ostream> Value) {
SecureLog = std::move(Value);
}
void setSecureLogUsed(bool Value) { SecureLogUsed = Value; }
void *allocate(unsigned Size, unsigned Align = 8) {
return Allocator.Allocate(Size, Align);
}
void deallocate(void *Ptr) {}
bool hadError() { return HadError; }
void reportError(SMLoc L, const Twine &Msg);
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L,
const Twine &Msg);
};
}
inline void *operator new(size_t Bytes, llvm::MCContext &C,
size_t Alignment = 8) LLVM_NOEXCEPT {
return C.allocate(Bytes, Alignment);
}
inline void operator delete(void *Ptr, llvm::MCContext &C,
size_t) LLVM_NOEXCEPT {
C.deallocate(Ptr);
}
inline void *operator new[](size_t Bytes, llvm::MCContext &C,
size_t Alignment = 8) LLVM_NOEXCEPT {
return C.allocate(Bytes, Alignment);
}
inline void operator delete[](void *Ptr, llvm::MCContext &C) LLVM_NOEXCEPT {
C.deallocate(Ptr);
}
#endif