#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/MC/MCDwarf.h"
+#include "llvm/MC/MCStreamer.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 {
/// Symbols - Bindings of names to symbols.
SymbolTable Symbols;
+ /// ELF sections can have a corresponding symbol. This maps one to the
+ /// other.
+ DenseMap<const MCSectionELF*, MCSymbol*> SectionSymbols;
+
/// A maping from a local label number and an instance count to a symbol.
/// For example, in the assembly
/// 1:
/// assembly source files.
unsigned GenDwarfFileNumber;
- /// The default initial text section that we generate dwarf debugging line
- /// info for when generating dwarf assembly source files.
- const MCSection *GenDwarfSection;
- /// Symbols created for the start and end of this section.
- MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym;
+ /// Symbols created for the start and end of each section, used for
+ /// generating the .debug_ranges and .debug_aranges sections.
+ MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >
+ SectionStartEndSyms;
/// The information gathered from labels that will have dwarf label
/// entries when generating dwarf assembly source files.
- std::vector<const MCGenDwarfLabelEntry *> MCGenDwarfLabelEntries;
+ std::vector<MCGenDwarfLabelEntry> MCGenDwarfLabelEntries;
/// The string to embed in the debug information for the compile unit, if
/// non-empty.
/// non-empty.
StringRef DwarfDebugProducer;
+ /// The maximum version of dwarf that we should emit.
+ uint16_t DwarfVersion;
+
/// Honor temporary labels, this is useful for debugging semantic
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID;
- void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
+ typedef std::pair<std::string, std::string> SectionGroupPair;
+ typedef std::tuple<std::string, std::string, int> SectionGroupTriple;
+
+ StringMap<const MCSectionMachO*> MachOUniquingMap;
+ std::map<SectionGroupPair, const MCSectionELF *> ELFUniquingMap;
+ std::map<SectionGroupTriple, const MCSectionCOFF *> COFFUniquingMap;
/// Do automatic reset in destructor
bool AutoReset;
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
- const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
- bool DoAutoReset = true);
+ const MCObjectFileInfo *MOFI,
+ const SourceMgr *Mgr = nullptr, bool DoAutoReset = true);
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
MCSymbol *GetOrCreateSymbol(StringRef Name);
MCSymbol *GetOrCreateSymbol(const Twine &Name);
+ MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
+
/// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const;
MCSymbol *LookupSymbol(const Twine &Name) const;
unsigned Flags, SectionKind Kind,
unsigned EntrySize, StringRef Group);
+ void renameELFSection(const MCSectionELF *Section, StringRef Name);
+
const MCSectionELF *CreateELFGroupSection();
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
SectionKind Kind,
- StringRef COMDATSymName,
- int Selection,
- const MCSectionCOFF *Assoc = 0);
+ StringRef COMDATSymName, int Selection);
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
const MCSectionCOFF *getCOFFSection(StringRef Section);
+ /// Gets or creates a section equivalent to Sec that is associated with the
+ /// section containing KeySym. For example, to create a debug info section
+ /// associated with an inline function, pass the normal debug info section
+ /// as Sec and the function symbol as KeySym.
+ const MCSectionCOFF *getAssociativeCOFFSection(const MCSectionCOFF *Sec,
+ const MCSymbol *KeySym);
+
/// @}
/// @name Dwarf Management
bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
- bool hasDwarfFiles() const {
- // Traverse MCDwarfFilesCUMap and check whether each entry is empty.
- for (const auto &FileTable : MCDwarfLineTablesCUMap)
- if (!FileTable.second.getMCDwarfFiles().empty())
- return true;
- return false;
- }
-
const std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const {
return MCDwarfLineTablesCUMap;
}
void setDwarfCompileUnitID(unsigned CUIndex) {
DwarfCompileUnitID = CUIndex;
}
- MCSymbol *getMCLineTableSymbol(unsigned ID) const {
- return getMCDwarfLineTable(ID).getLabel();
- }
- void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
- getMCDwarfLineTable(ID).setLabel(Sym);
- }
void setMCLineTableCompilationDir(unsigned CUID, StringRef CompilationDir) {
getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
}
void setGenDwarfFileNumber(unsigned FileNumber) {
GenDwarfFileNumber = FileNumber;
}
- const MCSection *getGenDwarfSection() { return GenDwarfSection; }
- void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
- MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
- void setGenDwarfSectionStartSym(MCSymbol *Sym) {
- GenDwarfSectionStartSym = Sym;
+ MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> > &
+ getGenDwarfSectionSyms() {
+ return SectionStartEndSyms;
}
- MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
- void setGenDwarfSectionEndSym(MCSymbol *Sym) {
- GenDwarfSectionEndSym = Sym;
+ std::pair<MapVector<const MCSection *,
+ std::pair<MCSymbol *, MCSymbol *> >::iterator,
+ bool>
+ addGenDwarfSection(const MCSection *Sec) {
+ return SectionStartEndSyms.insert(
+ std::make_pair(Sec, std::make_pair(nullptr, nullptr)));
}
- const std::vector<const MCGenDwarfLabelEntry *>
- &getMCGenDwarfLabelEntries() const {
+ void finalizeDwarfSections(MCStreamer &MCOS);
+ const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const {
return MCGenDwarfLabelEntries;
}
- void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E) {
+ void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E) {
MCGenDwarfLabelEntries.push_back(E);
}
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; }
// Unrecoverable error has occurred. 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);
+ LLVM_ATTRIBUTE_NORETURN void FatalError(SMLoc L, const Twine &Msg) const;
};
} // end namespace llvm